Skip to main content

voidmc_codec/primitives/
containers.rs

1use crate::primitives::vari::VarI32;
2use crate::{Decode, DecodeError, Encode};
3
4impl<T: Encode> Encode for Vec<T> {
5    fn encode(&self, buf: &mut Vec<u8>) {
6        VarI32(self.len() as i32).encode(buf);
7        for item in self {
8            item.encode(buf);
9        }
10    }
11}
12
13impl<T: Decode> Decode for Vec<T> {
14    fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
15        let len = VarI32::decode(buf)?.0;
16        if len < 0 {
17            return Err(DecodeError::InvalidLength);
18        }
19
20        let mut vec = Vec::with_capacity(len as usize);
21        for _ in 0..len {
22            vec.push(T::decode(buf)?);
23        }
24        Ok(vec)
25    }
26}
27
28impl Encode for String {
29    fn encode(&self, buf: &mut Vec<u8>) {
30        VarI32(self.len() as i32).encode(buf);
31        buf.extend_from_slice(self.as_bytes());
32    }
33}
34
35impl Decode for String {
36    fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
37        let len = VarI32::decode(buf)?.0;
38        if len < 0 {
39            return Err(DecodeError::InvalidLength);
40        }
41
42        let len = len as usize;
43        if buf.len() < len {
44            return Err(DecodeError::UnexpectedEof);
45        }
46
47        let (bytes, rest) = buf.split_at(len);
48        *buf = rest;
49
50        String::from_utf8(bytes.to_vec()).map_err(|_| DecodeError::InvalidLength)
51    }
52}
53
54impl<T: Encode> Encode for Option<T> {
55    fn encode(&self, buf: &mut Vec<u8>) {
56        match self {
57            Some(value) => {
58                true.encode(buf);
59                value.encode(buf);
60            }
61            None => {
62                false.encode(buf);
63            }
64        }
65    }
66}
67
68impl<T: Decode> Decode for Option<T> {
69    fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
70        let present = bool::decode(buf)?;
71        if present {
72            T::decode(buf).map(Some)
73        } else {
74            Ok(None)
75        }
76    }
77}
78
79#[cfg(test)]
80mod tests {
81    use super::*;
82
83    #[test]
84    fn test_vec_i32_empty() {
85        let value: Vec<i32> = vec![];
86        let mut buf = Vec::new();
87        value.encode(&mut buf);
88
89        assert_eq!(
90            buf.len(),
91            1,
92            "Empty vec should encode to single byte (length 0)"
93        );
94
95        let mut slice = buf.as_slice();
96        let decoded = Vec::<i32>::decode(&mut slice).unwrap();
97        assert_eq!(decoded, value);
98    }
99
100    #[test]
101    fn test_vec_i32_single() {
102        let value: Vec<i32> = vec![12345];
103        let mut buf = Vec::new();
104        value.encode(&mut buf);
105
106        let mut slice = buf.as_slice();
107        let decoded = Vec::<i32>::decode(&mut slice).unwrap();
108        assert_eq!(decoded, value);
109    }
110
111    #[test]
112    fn test_vec_i32_multiple() {
113        let value: Vec<i32> = vec![1, 2, 3, 4, 5];
114        let mut buf = Vec::new();
115        value.encode(&mut buf);
116
117        let mut slice = buf.as_slice();
118        let decoded = Vec::<i32>::decode(&mut slice).unwrap();
119        assert_eq!(decoded, value);
120    }
121
122    #[test]
123    fn test_vec_u8_bytes() {
124        let value: Vec<u8> = vec![1, 2, 3, 255, 0, 127];
125        let mut buf = Vec::new();
126        value.encode(&mut buf);
127
128        let mut slice = buf.as_slice();
129        let decoded = Vec::<u8>::decode(&mut slice).unwrap();
130        assert_eq!(decoded, value);
131    }
132
133    #[test]
134    fn test_vec_bool() {
135        let value: Vec<bool> = vec![true, false, true, true, false];
136        let mut buf = Vec::new();
137        value.encode(&mut buf);
138
139        let mut slice = buf.as_slice();
140        let decoded = Vec::<bool>::decode(&mut slice).unwrap();
141        assert_eq!(decoded, value);
142    }
143
144    #[test]
145    fn test_vec_large() {
146        let value: Vec<i32> = (0..1000).collect();
147        let mut buf = Vec::new();
148        value.encode(&mut buf);
149
150        let mut slice = buf.as_slice();
151        let decoded = Vec::<i32>::decode(&mut slice).unwrap();
152        assert_eq!(decoded, value);
153        assert_eq!(slice.len(), 0);
154    }
155
156    #[test]
157    fn test_vec_eof() {
158        let mut slice = &[][..];
159        let result = Vec::<i32>::decode(&mut slice);
160        assert_eq!(result, Err(DecodeError::UnexpectedEof));
161    }
162
163    #[test]
164    fn test_vec_invalid_length() {
165        let mut buf = Vec::new();
166        VarI32(-1).encode(&mut buf);
167
168        let mut slice = buf.as_slice();
169        let result = Vec::<i32>::decode(&mut slice);
170        assert_eq!(result, Err(DecodeError::InvalidLength));
171    }
172
173    #[test]
174    fn test_vec_empty_exact_bytes() {
175        let value: Vec<i32> = vec![];
176        let mut buf = Vec::new();
177        value.encode(&mut buf);
178        assert_eq!(buf, vec![0x00]);
179    }
180
181    #[test]
182    fn test_vec_u8_single_element() {
183        let value: Vec<u8> = vec![42];
184        let mut buf = Vec::new();
185        value.encode(&mut buf);
186        assert_eq!(buf, vec![0x01, 42]);
187    }
188
189    #[test]
190    fn test_vec_u8_exact_bytes() {
191        let value: Vec<u8> = vec![1, 2, 3];
192        let mut buf = Vec::new();
193        value.encode(&mut buf);
194        assert_eq!(buf, vec![0x03, 1, 2, 3]);
195    }
196
197    #[test]
198    fn test_vec_i32_exact_bytes() {
199        let value: Vec<i32> = vec![256];
200        let mut buf = Vec::new();
201        value.encode(&mut buf);
202        assert_eq!(buf, vec![0x01, 0x00, 0x00, 0x01, 0x00]);
203    }
204
205    #[test]
206    fn test_vec_bool_exact_bytes() {
207        let value: Vec<bool> = vec![true, false, true];
208        let mut buf = Vec::new();
209        value.encode(&mut buf);
210        assert_eq!(buf, vec![0x03, 0x01, 0x00, 0x01]);
211    }
212
213    #[test]
214    fn test_vec_length_encoded_correctly() {
215        for len in [0, 1, 5, 10, 127, 128, 255] {
216            let value: Vec<i32> = (0..len).map(|i| i as i32).collect();
217            let mut buf = Vec::new();
218            value.encode(&mut buf);
219
220            let mut slice = buf.as_slice();
221            let decoded = Vec::<i32>::decode(&mut slice).unwrap();
222            assert_eq!(decoded.len(), len, "Length {} not correctly encoded", len);
223            assert_eq!(decoded, value);
224        }
225    }
226
227    #[test]
228    fn test_vec_nested_vecs() {
229        let inner1: Vec<u8> = vec![1, 2];
230        let inner2: Vec<u8> = vec![3, 4, 5];
231        let value: Vec<Vec<u8>> = vec![inner1, inner2];
232
233        let mut buf = Vec::new();
234        value.encode(&mut buf);
235
236        let mut slice = buf.as_slice();
237        let decoded = Vec::<Vec<u8>>::decode(&mut slice).unwrap();
238        assert_eq!(decoded, value);
239    }
240
241    #[test]
242    fn test_vec_u8_large_exact_format() {
243        let value: Vec<u8> = vec![0xAA; 200];
244        let mut buf = Vec::new();
245        value.encode(&mut buf);
246
247        assert_eq!(buf[0..2], [0xC8, 0x01]);
248        for byte in buf.iter().skip(2) {
249            assert_eq!(*byte, 0xAA);
250        }
251    }
252
253    #[test]
254    fn test_vec_incomplete_data_error() {
255        let mut buf = Vec::new();
256        vec![1i32, 2i32, 3i32].encode(&mut buf);
257
258        let mut slice = &buf[0..5];
259        let result = Vec::<i32>::decode(&mut slice);
260        assert!(result.is_err());
261    }
262
263    #[test]
264    fn test_vec_roundtrip_mixed_types() {
265        let values: Vec<(u8, bool)> = vec![(1, true), (255, false)];
266        for (a, b) in values {
267            let vec_a: Vec<u8> = vec![a];
268            let vec_b: Vec<bool> = vec![b];
269
270            let mut buf_a = Vec::new();
271            vec_a.encode(&mut buf_a);
272            let mut slice_a = buf_a.as_slice();
273            let decoded_a = Vec::<u8>::decode(&mut slice_a).unwrap();
274            assert_eq!(decoded_a, vec_a);
275
276            let mut buf_b = Vec::new();
277            vec_b.encode(&mut buf_b);
278            let mut slice_b = buf_b.as_slice();
279            let decoded_b = Vec::<bool>::decode(&mut slice_b).unwrap();
280            assert_eq!(decoded_b, vec_b);
281        }
282    }
283
284    #[test]
285    fn test_string_empty() {
286        let value = String::new();
287        let mut buf = Vec::new();
288        value.encode(&mut buf);
289
290        let mut slice = buf.as_slice();
291        let decoded = String::decode(&mut slice).unwrap();
292        assert_eq!(decoded, value);
293    }
294
295    #[test]
296    fn test_string_simple() {
297        let value = String::from("hello");
298        let mut buf = Vec::new();
299        value.encode(&mut buf);
300
301        let mut slice = buf.as_slice();
302        let decoded = String::decode(&mut slice).unwrap();
303        assert_eq!(decoded, value);
304    }
305
306    #[test]
307    fn test_string_with_unicode() {
308        let value = String::from("hello🎮world");
309        let mut buf = Vec::new();
310        value.encode(&mut buf);
311
312        let mut slice = buf.as_slice();
313        let decoded = String::decode(&mut slice).unwrap();
314        assert_eq!(decoded, value);
315    }
316
317    #[test]
318    fn test_string_long() {
319        let value = String::from(
320            "The quick brown fox jumps over the lazy dog. \
321            This is a longer string to test that the VarI32 length prefix works correctly \
322            for strings longer than 127 characters.",
323        );
324        let mut buf = Vec::new();
325        value.encode(&mut buf);
326
327        let mut slice = buf.as_slice();
328        let decoded = String::decode(&mut slice).unwrap();
329        assert_eq!(decoded, value);
330    }
331
332    #[test]
333    fn test_string_incomplete_data() {
334        let value = String::from("hello");
335        let mut buf = Vec::new();
336        value.encode(&mut buf);
337
338        // Try to decode with only partial data
339        let mut slice = &buf[0..3];
340        let result = String::decode(&mut slice);
341        assert!(result.is_err());
342    }
343
344    #[test]
345    fn test_string_invalid_utf8() {
346        // Create a buffer with invalid UTF-8
347        let mut buf = Vec::new();
348        VarI32(2).encode(&mut buf); // Length = 2
349        buf.push(0xFF);
350        buf.push(0xFE); // Invalid UTF-8 sequence
351
352        let mut slice = buf.as_slice();
353        let result = String::decode(&mut slice);
354        assert!(result.is_err());
355    }
356
357    #[test]
358    fn test_option_some_i32() {
359        let value: Option<i32> = Some(42);
360        let mut buf = Vec::new();
361        value.encode(&mut buf);
362
363        // Should be: [true/0x01] + [42 as 4 bytes big-endian]
364        assert_eq!(buf.len(), 5);
365        assert_eq!(buf[0], 1); // true
366
367        let mut slice = buf.as_slice();
368        let decoded: Option<i32> = Option::decode(&mut slice).unwrap();
369        assert_eq!(decoded, Some(42));
370    }
371
372    #[test]
373    fn test_option_none_i32() {
374        let value: Option<i32> = None;
375        let mut buf = Vec::new();
376        value.encode(&mut buf);
377
378        // Should be: [false/0x00]
379        assert_eq!(buf.len(), 1);
380        assert_eq!(buf[0], 0); // false
381
382        let mut slice = buf.as_slice();
383        let decoded: Option<i32> = Option::decode(&mut slice).unwrap();
384        assert_eq!(decoded, None);
385    }
386
387    #[test]
388    fn test_option_some_string() {
389        let value: Option<String> = Some(String::from("hello"));
390        let mut buf = Vec::new();
391        value.encode(&mut buf);
392
393        // Should be: [true/0x01] + [VarI32(5)] + [hello as UTF-8]
394        assert!(buf.len() > 1);
395        assert_eq!(buf[0], 1); // true
396
397        let mut slice = buf.as_slice();
398        let decoded: Option<String> = Option::decode(&mut slice).unwrap();
399        assert_eq!(decoded, Some(String::from("hello")));
400    }
401
402    #[test]
403    fn test_option_some_vec() {
404        let value: Option<Vec<i32>> = Some(vec![1, 2, 3]);
405        let mut buf = Vec::new();
406        value.encode(&mut buf);
407
408        // Should be: [true/0x01] + [VarI32(3)] + [1, 2, 3 as 4-byte big-endian each]
409        assert!(buf.len() > 1);
410        assert_eq!(buf[0], 1); // true
411
412        let mut slice = buf.as_slice();
413        let decoded: Option<Vec<i32>> = Option::decode(&mut slice).unwrap();
414        assert_eq!(decoded, Some(vec![1, 2, 3]));
415    }
416
417    #[test]
418    fn test_option_nested() {
419        let value: Option<Option<i32>> = Some(Some(100));
420        let mut buf = Vec::new();
421        value.encode(&mut buf);
422
423        let mut slice = buf.as_slice();
424        let decoded: Option<Option<i32>> = Option::decode(&mut slice).unwrap();
425        assert_eq!(decoded, Some(Some(100)));
426    }
427
428    #[test]
429    fn test_option_nested_none() {
430        let value: Option<Option<i32>> = Some(None);
431        let mut buf = Vec::new();
432        value.encode(&mut buf);
433
434        let mut slice = buf.as_slice();
435        let decoded: Option<Option<i32>> = Option::decode(&mut slice).unwrap();
436        assert_eq!(decoded, Some(None));
437    }
438
439    #[test]
440    fn test_option_roundtrip() {
441        let cases: Vec<Option<i32>> = vec![Some(0), Some(-1), Some(2147483647), None];
442
443        for value in cases {
444            let mut buf = Vec::new();
445            value.encode(&mut buf);
446
447            let mut slice = buf.as_slice();
448            let decoded = Option::decode(&mut slice).unwrap();
449            assert_eq!(decoded, value);
450        }
451    }
452
453    #[test]
454    fn test_option_incomplete_data() {
455        // Create a buffer with only the presence boolean, no data
456        let mut buf = Vec::new();
457        true.encode(&mut buf); // Present, but no i32 data follows
458
459        let mut slice = buf.as_slice();
460        let result: Result<Option<i32>, _> = Option::decode(&mut slice);
461        assert!(result.is_err());
462    }
463}