lumen_plugin_abi/
codec.rs1use bincode::Options;
10use serde::Serialize;
11use serde::de::DeserializeOwned;
12
13pub const MAX_PAYLOAD: u64 = 512 * 1024 * 1024;
16
17pub fn encode<T: Serialize>(value: &T) -> Result<Vec<u8>, String> {
19 bincode::serialize(value).map_err(|e| e.to_string())
20}
21
22pub fn decode<T: DeserializeOwned>(bytes: &[u8]) -> Result<T, String> {
24 bincode::DefaultOptions::new()
25 .with_fixint_encoding()
26 .with_limit(MAX_PAYLOAD)
27 .deserialize(bytes)
28 .map_err(|e| e.to_string())
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34
35 #[test]
36 fn round_trips() {
37 let v: Vec<String> = vec!["a".into(), "bc".into()];
38 let bytes = encode(&v).unwrap();
39 let back: Vec<String> = decode(&bytes).unwrap();
40 assert_eq!(v, back);
41 }
42
43 #[test]
44 fn truncated_is_an_error_not_a_panic() {
45 let bytes = encode(&vec![1u64, 2, 3]).unwrap();
46 let err = decode::<Vec<u64>>(&bytes[..bytes.len() - 3]).unwrap_err();
47 assert!(!err.is_empty());
48 }
49
50 #[test]
51 fn oversized_length_prefix_is_rejected() {
52 let bytes = (u64::MAX).to_le_bytes().to_vec();
54 assert!(decode::<Vec<u8>>(&bytes).is_err());
55 }
56}