procwire_client/codec/
msgpack.rs1use crate::error::Result;
32
33pub struct MsgPackCodec;
39
40impl MsgPackCodec {
41 #[inline]
49 pub fn encode<T: serde::Serialize>(value: &T) -> Result<Vec<u8>> {
50 Ok(rmp_serde::to_vec_named(value)?)
52 }
53
54 #[inline]
60 pub fn decode<T: serde::de::DeserializeOwned>(bytes: &[u8]) -> Result<T> {
61 Ok(rmp_serde::from_slice(bytes)?)
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use serde::{Deserialize, Serialize};
69
70 #[derive(Serialize, Deserialize, PartialEq, Debug)]
71 struct TestStruct {
72 id: u32,
73 name: String,
74 active: bool,
75 }
76
77 #[test]
78 fn test_encode_decode_struct() {
79 let original = TestStruct {
80 id: 42,
81 name: "test".to_string(),
82 active: true,
83 };
84
85 let encoded = MsgPackCodec::encode(&original).unwrap();
86 let decoded: TestStruct = MsgPackCodec::decode(&encoded).unwrap();
87
88 assert_eq!(decoded, original);
89 }
90
91 #[test]
92 fn test_encode_decode_primitives() {
93 let s = "hello world";
95 let encoded = MsgPackCodec::encode(&s).unwrap();
96 let decoded: String = MsgPackCodec::decode(&encoded).unwrap();
97 assert_eq!(decoded, s);
98
99 let n: i64 = 12345;
101 let encoded = MsgPackCodec::encode(&n).unwrap();
102 let decoded: i64 = MsgPackCodec::decode(&encoded).unwrap();
103 assert_eq!(decoded, n);
104
105 let b = true;
107 let encoded = MsgPackCodec::encode(&b).unwrap();
108 let decoded: bool = MsgPackCodec::decode(&encoded).unwrap();
109 assert_eq!(decoded, b);
110 }
111
112 #[test]
113 fn test_encode_decode_collections() {
114 let vec = vec![1, 2, 3, 4, 5];
116 let encoded = MsgPackCodec::encode(&vec).unwrap();
117 let decoded: Vec<i32> = MsgPackCodec::decode(&encoded).unwrap();
118 assert_eq!(decoded, vec);
119
120 use std::collections::HashMap;
122 let mut map = HashMap::new();
123 map.insert("key1".to_string(), 100);
124 map.insert("key2".to_string(), 200);
125
126 let encoded = MsgPackCodec::encode(&map).unwrap();
127 let decoded: HashMap<String, i32> = MsgPackCodec::decode(&encoded).unwrap();
128 assert_eq!(decoded, map);
129 }
130
131 #[test]
132 fn test_encode_decode_nested() {
133 #[derive(Serialize, Deserialize, PartialEq, Debug)]
134 struct Inner {
135 value: i32,
136 }
137
138 #[derive(Serialize, Deserialize, PartialEq, Debug)]
139 struct Outer {
140 inner: Inner,
141 items: Vec<String>,
142 }
143
144 let original = Outer {
145 inner: Inner { value: 999 },
146 items: vec!["a".to_string(), "b".to_string()],
147 };
148
149 let encoded = MsgPackCodec::encode(&original).unwrap();
150 let decoded: Outer = MsgPackCodec::decode(&encoded).unwrap();
151
152 assert_eq!(decoded, original);
153 }
154
155 #[test]
156 fn test_encode_decode_option() {
157 let some_val: Option<i32> = Some(42);
158 let encoded = MsgPackCodec::encode(&some_val).unwrap();
159 let decoded: Option<i32> = MsgPackCodec::decode(&encoded).unwrap();
160 assert_eq!(decoded, some_val);
161
162 let none_val: Option<i32> = None;
163 let encoded = MsgPackCodec::encode(&none_val).unwrap();
164 let decoded: Option<i32> = MsgPackCodec::decode(&encoded).unwrap();
165 assert_eq!(decoded, none_val);
166 }
167
168 #[test]
169 fn test_to_vec_named_produces_map_format() {
170 let test = TestStruct {
173 id: 1,
174 name: "x".to_string(),
175 active: false,
176 };
177
178 let encoded = MsgPackCodec::encode(&test).unwrap();
179
180 assert_eq!(
183 encoded[0] & 0xF0,
184 0x80,
185 "Expected map format (0x8X), got {:02X}",
186 encoded[0]
187 );
188 }
189
190 #[test]
191 fn test_decode_error_on_invalid_data() {
192 let invalid = b"not valid msgpack";
193 let result: Result<TestStruct> = MsgPackCodec::decode(invalid);
194 assert!(result.is_err());
195 }
196
197 #[test]
198 fn test_empty_struct() {
199 #[derive(Serialize, Deserialize, PartialEq, Debug)]
200 struct Empty {}
201
202 let empty = Empty {};
203 let encoded = MsgPackCodec::encode(&empty).unwrap();
204 let decoded: Empty = MsgPackCodec::decode(&encoded).unwrap();
205 assert_eq!(decoded, empty);
206 }
207
208 #[test]
209 fn test_nodejs_interop_simple_object() {
210 #[derive(Serialize, Deserialize, PartialEq, Debug)]
215 struct SimpleObj {
216 id: i32,
217 name: String,
218 }
219
220 let obj = SimpleObj {
221 id: 1,
222 name: "test".to_string(),
223 };
224
225 let encoded = MsgPackCodec::encode(&obj).unwrap();
226
227 assert_eq!(encoded[0], 0x82, "Expected fixmap with 2 elements");
229
230 let decoded: SimpleObj = MsgPackCodec::decode(&encoded).unwrap();
232 assert_eq!(decoded, obj);
233 }
234
235 #[test]
236 fn test_nodejs_interop_number_types() {
237 let n: u8 = 255;
240 let encoded = MsgPackCodec::encode(&n).unwrap();
241 let decoded: u8 = MsgPackCodec::decode(&encoded).unwrap();
242 assert_eq!(decoded, n);
243
244 let n: i32 = -12345;
246 let encoded = MsgPackCodec::encode(&n).unwrap();
247 let decoded: i32 = MsgPackCodec::decode(&encoded).unwrap();
248 assert_eq!(decoded, n);
249
250 let n: f64 = 3.14159;
252 let encoded = MsgPackCodec::encode(&n).unwrap();
253 let decoded: f64 = MsgPackCodec::decode(&encoded).unwrap();
254 assert!((decoded - n).abs() < f64::EPSILON);
255 }
256
257 #[test]
258 fn test_nodejs_interop_array() {
259 let arr = vec!["hello", "world", "test"];
261 let encoded = MsgPackCodec::encode(&arr).unwrap();
262
263 assert_eq!(encoded[0], 0x93, "Expected fixarray with 3 elements");
265
266 let decoded: Vec<String> = MsgPackCodec::decode(&encoded).unwrap();
267 assert_eq!(decoded, arr);
268 }
269
270 #[test]
271 fn test_nodejs_interop_null() {
272 let val: Option<i32> = None;
274 let encoded = MsgPackCodec::encode(&val).unwrap();
275
276 assert_eq!(encoded, vec![0xc0], "None should encode as msgpack nil");
278
279 let decoded: Option<i32> = MsgPackCodec::decode(&encoded).unwrap();
280 assert_eq!(decoded, None);
281 }
282
283 #[test]
284 fn test_nodejs_interop_binary_buffer() {
285 let data: Vec<u8> = vec![0x01, 0x02, 0x03, 0x04, 0x05];
288 let encoded = MsgPackCodec::encode(&serde_bytes::Bytes::new(&data)).unwrap();
289
290 assert_eq!(encoded[0], 0xc4, "Expected bin8 format");
292
293 let decoded: serde_bytes::ByteBuf = MsgPackCodec::decode(&encoded).unwrap();
294 assert_eq!(decoded.as_ref(), &data);
295 }
296}