Skip to main content

external_buffered_stream/serde/
bincode.rs

1use bincode::{config, decode_from_slice, encode_to_vec};
2pub use bincode::{Decode, Encode};
3
4use crate::Error;
5
6use super::ExternalBufferSerde;
7
8impl<T> ExternalBufferSerde for T
9where
10    T: Encode + Decode<()>,
11{
12    fn into_external_buffer(self) -> Result<Vec<u8>, Error> {
13        Ok(encode_to_vec(self, config::standard())?)
14    }
15
16    fn from_external_buffer(buffer: &[u8]) -> Result<T, Error> {
17        Ok(decode_from_slice(buffer, config::standard()).map(|(u, _)| u)?)
18    }
19}
20
21#[cfg(test)]
22mod tests {
23    use super::ExternalBufferSerde;
24    use bincode::{Decode, Encode};
25
26    #[derive(Debug, Clone, PartialEq, Encode, Decode)]
27    struct TestStruct {
28        id: u32,
29        name: String,
30        active: bool,
31    }
32
33    #[derive(Debug, Clone, PartialEq, Encode, Decode)]
34    struct SimpleStruct {
35        value: i32,
36    }
37
38    #[test]
39    fn test_basic_encode_decode() {
40        let original = TestStruct {
41            id: 42,
42            name: "test".to_string(),
43            active: true,
44        };
45
46        // Test encoding
47        let encoded = original
48            .clone()
49            .into_external_buffer()
50            .expect("Failed to encode");
51        assert!(!encoded.is_empty(), "Encoded data should not be empty");
52
53        // Test decoding
54        let decoded = TestStruct::from_external_buffer(&encoded).expect("Failed to decode");
55        assert_eq!(original, decoded, "Decoded value should match original");
56    }
57
58    #[test]
59    fn test_simple_types() {
60        // Test with integer
61        let original_int = 12345i32;
62        let encoded = original_int
63            .into_external_buffer()
64            .expect("Failed to encode i32");
65        let decoded = i32::from_external_buffer(&encoded).expect("Failed to decode i32");
66        assert_eq!(original_int, decoded);
67
68        // Test with string
69        let original_string = "Hello, World!".to_string();
70        let encoded = original_string
71            .clone()
72            .into_external_buffer()
73            .expect("Failed to encode String");
74        let decoded = String::from_external_buffer(&encoded).expect("Failed to decode String");
75        assert_eq!(original_string, decoded);
76
77        // Test with boolean
78        let original_bool = true;
79        let encoded = original_bool
80            .into_external_buffer()
81            .expect("Failed to encode bool");
82        let decoded = bool::from_external_buffer(&encoded).expect("Failed to decode bool");
83        assert_eq!(original_bool, decoded);
84    }
85
86    #[test]
87    fn test_empty_string() {
88        let original = String::new();
89        let encoded = original
90            .clone()
91            .into_external_buffer()
92            .expect("Failed to encode empty string");
93        let decoded =
94            String::from_external_buffer(&encoded).expect("Failed to decode empty string");
95        assert_eq!(original, decoded);
96    }
97
98    #[test]
99    fn test_zero_values() {
100        let original = SimpleStruct { value: 0 };
101        let encoded = original
102            .clone()
103            .into_external_buffer()
104            .expect("Failed to encode zero value");
105        let decoded =
106            SimpleStruct::from_external_buffer(&encoded).expect("Failed to decode zero value");
107        assert_eq!(original, decoded);
108    }
109
110    #[test]
111    fn test_negative_values() {
112        let original = SimpleStruct { value: -42 };
113        let encoded = original
114            .clone()
115            .into_external_buffer()
116            .expect("Failed to encode negative value");
117        let decoded =
118            SimpleStruct::from_external_buffer(&encoded).expect("Failed to decode negative value");
119        assert_eq!(original, decoded);
120    }
121
122    #[test]
123    fn test_large_struct() {
124        let original = TestStruct {
125            id: u32::MAX,
126            name: "a".repeat(1000), // Large string
127            active: false,
128        };
129        let encoded = original
130            .clone()
131            .into_external_buffer()
132            .expect("Failed to encode large struct");
133        let decoded =
134            TestStruct::from_external_buffer(&encoded).expect("Failed to decode large struct");
135        assert_eq!(original, decoded);
136    }
137
138    #[test]
139    fn test_decode_invalid_data() {
140        // Test with completely invalid data
141        let invalid_data = vec![0xFF, 0xFF, 0xFF, 0xFF];
142        let result: Result<TestStruct, _> = TestStruct::from_external_buffer(&invalid_data);
143        assert!(result.is_err(), "Should fail to decode invalid data");
144
145        // Verify it's a decode error
146        match result {
147            Err(crate::Error::DecodeError(_)) => {}
148            _ => panic!("Expected DecodeError"),
149        }
150    }
151
152    #[test]
153    fn test_decode_empty_data() {
154        let empty_data = vec![];
155        let result: Result<i32, _> = i32::from_external_buffer(&empty_data);
156        assert!(result.is_err(), "Should fail to decode empty data");
157    }
158
159    #[test]
160    fn test_decode_truncated_data() {
161        // Encode a struct first
162        let original = TestStruct {
163            id: 42,
164            name: "test".to_string(),
165            active: true,
166        };
167        let mut encoded = original.into_external_buffer().expect("Failed to encode");
168
169        // Truncate the data
170        encoded.truncate(encoded.len() / 2);
171
172        let result: Result<TestStruct, _> = TestStruct::from_external_buffer(&encoded);
173        assert!(result.is_err(), "Should fail to decode truncated data");
174    }
175
176    #[test]
177    fn test_roundtrip_multiple_times() {
178        let mut current = TestStruct {
179            id: 1,
180            name: "initial".to_string(),
181            active: true,
182        };
183
184        // Perform multiple encode/decode cycles
185        for i in 0..10 {
186            let encoded = current
187                .clone()
188                .into_external_buffer()
189                .expect("Failed to encode in cycle");
190            current =
191                TestStruct::from_external_buffer(&encoded).expect("Failed to decode in cycle");
192            current.id = i + 2; // Modify for next iteration
193        }
194
195        assert_eq!(current.id, 11);
196        assert_eq!(current.name, "initial");
197        assert_eq!(current.active, true);
198    }
199
200    #[test]
201    fn test_vec_serialization() {
202        let original = vec![1, 2, 3, 4, 5];
203        let encoded = original
204            .clone()
205            .into_external_buffer()
206            .expect("Failed to encode vec");
207        let decoded: Vec<i32> = Vec::from_external_buffer(&encoded).expect("Failed to decode vec");
208        assert_eq!(original, decoded);
209    }
210
211    #[test]
212    fn test_option_serialization() {
213        // Test Some value
214        let original_some = Some(42i32);
215        let encoded = original_some
216            .into_external_buffer()
217            .expect("Failed to encode Some");
218        let decoded: Option<i32> =
219            Option::from_external_buffer(&encoded).expect("Failed to decode Some");
220        assert_eq!(original_some, decoded);
221
222        // Test None value
223        let original_none: Option<i32> = None;
224        let encoded = original_none
225            .into_external_buffer()
226            .expect("Failed to encode None");
227        let decoded: Option<i32> =
228            Option::from_external_buffer(&encoded).expect("Failed to decode None");
229        assert_eq!(original_none, decoded);
230    }
231
232    #[test]
233    fn test_tuple_serialization() {
234        let original = (42i32, "hello".to_string(), true);
235        let encoded = original
236            .clone()
237            .into_external_buffer()
238            .expect("Failed to encode tuple");
239        let decoded: (i32, String, bool) =
240            <(i32, String, bool)>::from_external_buffer(&encoded).expect("Failed to decode tuple");
241        assert_eq!(original, decoded);
242    }
243
244    #[test]
245    fn test_nested_struct_serialization() {
246        #[derive(Debug, Clone, PartialEq, Encode, Decode)]
247        struct NestedStruct {
248            inner: TestStruct,
249            count: u64,
250            values: Vec<i32>,
251        }
252
253        let original = NestedStruct {
254            inner: TestStruct {
255                id: 123,
256                name: "nested".to_string(),
257                active: true,
258            },
259            count: 456,
260            values: vec![1, 2, 3, 4, 5],
261        };
262
263        let encoded = original
264            .clone()
265            .into_external_buffer()
266            .expect("Failed to encode nested struct");
267        let decoded: NestedStruct =
268            NestedStruct::from_external_buffer(&encoded).expect("Failed to decode nested struct");
269        assert_eq!(original, decoded);
270    }
271
272    #[test]
273    fn test_empty_vec_serialization() {
274        let original: Vec<i32> = vec![];
275        let encoded = original
276            .clone()
277            .into_external_buffer()
278            .expect("Failed to encode empty vec");
279        let decoded: Vec<i32> =
280            Vec::from_external_buffer(&encoded).expect("Failed to decode empty vec");
281        assert_eq!(original, decoded);
282    }
283
284    #[test]
285    fn test_large_vec_serialization() {
286        let original: Vec<u64> = (0..10000).collect();
287        let encoded = original
288            .clone()
289            .into_external_buffer()
290            .expect("Failed to encode large vec");
291        let decoded: Vec<u64> =
292            Vec::from_external_buffer(&encoded).expect("Failed to decode large vec");
293        assert_eq!(original, decoded);
294    }
295
296    #[test]
297    fn test_enum_serialization() {
298        #[derive(Debug, Clone, PartialEq, Encode, Decode)]
299        enum TestEnum {
300            Variant1,
301            Variant2(i32),
302            Variant3 { name: String, value: u32 },
303        }
304
305        // Test simple variant
306        let original1 = TestEnum::Variant1;
307        let encoded1 = original1
308            .clone()
309            .into_external_buffer()
310            .expect("Failed to encode enum variant1");
311        let decoded1: TestEnum =
312            TestEnum::from_external_buffer(&encoded1).expect("Failed to decode enum variant1");
313        assert_eq!(original1, decoded1);
314
315        // Test variant with data
316        let original2 = TestEnum::Variant2(42);
317        let encoded2 = original2
318            .clone()
319            .into_external_buffer()
320            .expect("Failed to encode enum variant2");
321        let decoded2: TestEnum =
322            TestEnum::from_external_buffer(&encoded2).expect("Failed to decode enum variant2");
323        assert_eq!(original2, decoded2);
324
325        // Test variant with struct-like data
326        let original3 = TestEnum::Variant3 {
327            name: "test".to_string(),
328            value: 123,
329        };
330        let encoded3 = original3
331            .clone()
332            .into_external_buffer()
333            .expect("Failed to encode enum variant3");
334        let decoded3: TestEnum =
335            TestEnum::from_external_buffer(&encoded3).expect("Failed to decode enum variant3");
336        assert_eq!(original3, decoded3);
337    }
338
339    #[test]
340    fn test_buffer_size_consistency() {
341        let test_data = TestStruct {
342            id: 42,
343            name: "consistency_test".to_string(),
344            active: true,
345        };
346
347        // Encode the same data multiple times and verify buffer size is consistent
348        let encoded1 = test_data
349            .clone()
350            .into_external_buffer()
351            .expect("First encoding failed");
352        let encoded2 = test_data
353            .clone()
354            .into_external_buffer()
355            .expect("Second encoding failed");
356        let encoded3 = test_data
357            .clone()
358            .into_external_buffer()
359            .expect("Third encoding failed");
360
361        assert_eq!(
362            encoded1.len(),
363            encoded2.len(),
364            "Buffer sizes should be consistent"
365        );
366        assert_eq!(
367            encoded2.len(),
368            encoded3.len(),
369            "Buffer sizes should be consistent"
370        );
371        assert_eq!(encoded1, encoded2, "Encoded buffers should be identical");
372        assert_eq!(encoded2, encoded3, "Encoded buffers should be identical");
373    }
374
375    #[test]
376    fn test_extreme_values() {
377        // Test with extreme integer values
378        let max_u32 = u32::MAX;
379        let encoded = max_u32
380            .into_external_buffer()
381            .expect("Failed to encode max u32");
382        let decoded = u32::from_external_buffer(&encoded).expect("Failed to decode max u32");
383        assert_eq!(max_u32, decoded);
384
385        let min_i32 = i32::MIN;
386        let encoded = min_i32
387            .into_external_buffer()
388            .expect("Failed to encode min i32");
389        let decoded = i32::from_external_buffer(&encoded).expect("Failed to decode min i32");
390        assert_eq!(min_i32, decoded);
391
392        let max_i64 = i64::MAX;
393        let encoded = max_i64
394            .into_external_buffer()
395            .expect("Failed to encode max i64");
396        let decoded = i64::from_external_buffer(&encoded).expect("Failed to decode max i64");
397        assert_eq!(max_i64, decoded);
398    }
399}