Skip to main content

bincake_core/
lib.rs

1mod error;
2mod read_write;
3mod serialize;
4mod serialize_num;
5mod serialize_tuple;
6mod sized_vec;
7
8/// The type used to represent the length of a string when serialized.
9pub type StringSize = u32;
10
11// re-export dependency as used in public API
12pub use taped::*;
13
14// flatten modules
15pub use self::{error::*, read_write::*, serialize::*, sized_vec::*};
16
17#[cfg(test)]
18mod tests {
19    use taped::ToTape;
20
21    use crate::{
22        error::{DecodeError, EncodeError},
23        read_write::{Read, Write},
24        serialize::Serialize,
25        sized_vec::{Vec8, Vec16, Vec32},
26        vec8, vec16, vec32, write_all,
27    };
28
29    // Helper function to round-trip test
30    fn round_trip<T: Serialize + PartialEq + std::fmt::Debug>(value: T) {
31        let mut buffer = vec![];
32        buffer.write(&value).expect("Failed to write");
33
34        let mut src = buffer.to_tape();
35        let decoded = src.read::<T>().expect("Failed to read");
36
37        dbg!(&src);
38        assert_eq!(value, decoded, "Round-trip failed");
39        assert_eq!(src.rest().len(), 0, "Not all bytes consumed");
40    }
41
42    #[test]
43    fn test_bool_serialization() {
44        round_trip(true);
45        round_trip(false);
46    }
47
48    #[test]
49    fn test_u8_serialization() {
50        round_trip(0u8);
51        round_trip(127u8);
52        round_trip(255u8);
53    }
54
55    #[test]
56    fn test_u16_serialization() {
57        round_trip(0u16);
58        round_trip(256u16);
59        round_trip(u16::MAX);
60    }
61
62    #[test]
63    fn test_u32_serialization() {
64        round_trip(0u32);
65        round_trip(65536u32);
66        round_trip(u32::MAX);
67    }
68
69    #[test]
70    fn test_signed_integers() {
71        round_trip(-128i8);
72        round_trip(127i8);
73        round_trip(-32768i16);
74        round_trip(32767i16);
75        round_trip(i32::MIN);
76        round_trip(i32::MAX);
77        round_trip(i64::MIN);
78        round_trip(i64::MAX);
79        round_trip(i128::MIN);
80        round_trip(i128::MAX);
81    }
82
83    #[test]
84    fn test_floats() {
85        round_trip(0.0f32);
86        round_trip(-0.0f32);
87        round_trip(std::f32::consts::PI);
88        round_trip(f32::INFINITY);
89        round_trip(f32::NEG_INFINITY);
90
91        round_trip(0.0f64);
92        round_trip(std::f64::consts::E);
93        round_trip(f64::INFINITY);
94        round_trip(f64::NEG_INFINITY);
95    }
96
97    #[test]
98    fn test_float_nan() {
99        let mut buffer = vec![];
100        buffer.write(&f32::NAN).unwrap();
101
102        let mut src = buffer.to_tape();
103        let decoded = src.read::<f32>().unwrap();
104
105        assert!(decoded.is_nan(), "NaN not preserved");
106    }
107
108    #[test]
109    fn test_string_serialization() {
110        round_trip(String::new());
111        round_trip("hello".to_string());
112        round_trip("Hello, World! 🦀".to_string());
113        round_trip("Multi\nLine\nString".to_string());
114
115        // Long string
116        let long = "a".repeat(1000);
117        round_trip(long);
118    }
119
120    #[test]
121    fn test_string_utf8() {
122        round_trip("日本語".to_string());
123        round_trip("Ñoño español".to_string());
124        round_trip("🎉🎊✨".to_string());
125    }
126
127    #[test]
128    fn test_tuples() {
129        round_trip((42u32, true));
130        round_trip((1u8, 2u16, 3u32));
131        round_trip(("hello".to_string(), 123i32));
132    }
133
134    #[test]
135    fn test_nested_tuples() {
136        round_trip(((1u8, 2u8), (3u8, 4u8)));
137    }
138
139    #[test]
140    fn test_vec8() {
141        let empty: Vec8<u32> = vec8![];
142        round_trip(empty);
143
144        let small = vec8![1u32, 2, 3, 4, 5];
145        round_trip(small);
146
147        // Max size for Vec8
148        let max_vec8 = vec8![0u8; 255];
149        round_trip(max_vec8);
150    }
151
152    #[test]
153    fn test_vec16() {
154        let empty: Vec16<u32> = vec16![];
155        round_trip(empty);
156
157        let medium = vec16![100u32; 300];
158        round_trip(medium);
159    }
160
161    #[test]
162    fn test_vec32() {
163        let empty: Vec32<u32> = vec32![];
164        round_trip(empty);
165
166        let large = vec32![42u32; 10000];
167        round_trip(large);
168    }
169
170    #[test]
171    fn test_vec_of_strings() {
172        let strings = vec32!["hello".to_string(), "world".to_string(), "🦀".to_string(),];
173        round_trip(strings);
174    }
175
176    #[test]
177    fn test_nested_vecs() {
178        let nested = vec32![vec8![1u8, 2, 3], vec8![4, 5], vec8![]];
179        round_trip(nested);
180    }
181
182    #[test]
183    fn test_little_endian_encoding() {
184        // Verify little-endian byte order
185        let mut buffer = vec![];
186        buffer.write(&0x12345678u32).unwrap();
187
188        assert_eq!(buffer, vec![0x78, 0x56, 0x34, 0x12]);
189    }
190
191    #[test]
192    fn test_string_length_prefix() {
193        // Verify string is prefixed with u32 length
194        let mut buffer = vec![];
195        buffer.write(&"abc".to_string()).unwrap();
196
197        // First 4 bytes should be length (3 in little-endian)
198        assert_eq!(buffer[0..4], [3, 0, 0, 0]);
199        // Next 3 bytes should be the string
200        assert_eq!(buffer[4..7], [b'a', b'b', b'c']);
201    }
202
203    #[test]
204    fn test_vec_length_prefix() {
205        let mut buffer = vec![];
206        buffer.write(&vec32![1u8, 2, 3]).unwrap();
207
208        // First 4 bytes should be length (3 in little-endian)
209        assert_eq!(buffer[0..4], [3, 0, 0, 0]);
210        // Next 3 bytes should be the elements
211        assert_eq!(buffer[4..7], [1, 2, 3]);
212    }
213
214    #[test]
215    fn test_empty_buffer_error() {
216        let buffer = [];
217        let mut src = buffer.to_tape();
218
219        let result = src.read::<u32>();
220        assert!(matches!(result, Err(DecodeError::Exhausted { .. })));
221    }
222
223    #[test]
224    fn test_truncated_data() {
225        let mut buffer = vec![];
226        buffer.write(&42u32).unwrap();
227
228        // Only provide 2 bytes instead of 4
229        let truncated = &buffer[0..2];
230        let mut src = truncated.to_tape();
231
232        let result = src.read::<u32>();
233        assert!(matches!(result, Err(DecodeError::Exhausted { .. })));
234    }
235
236    #[test]
237    fn test_truncated_string() {
238        let mut buffer = vec![];
239        buffer.write(&"hello".to_string()).unwrap();
240
241        // Truncate the buffer
242        let truncated = &buffer[0..6]; // Length prefix + only 2 chars
243        let mut src = truncated.to_tape();
244
245        let result = src.read::<String>();
246        assert!(matches!(result, Err(DecodeError::Exhausted { .. })));
247    }
248
249    #[test]
250    fn test_invalid_utf8() {
251        // Manually construct invalid UTF-8 in string format
252        let mut buffer = vec![];
253        // Length: 2
254        buffer.extend_from_slice(&[2, 0, 0, 0]);
255        // Invalid UTF-8 sequence
256        buffer.extend_from_slice(&[0xFF, 0xFE]);
257
258        let mut src = buffer.to_tape();
259        let result = src.read::<String>();
260
261        assert!(matches!(result, Err(DecodeError::Other { .. })));
262    }
263
264    #[test]
265    fn test_truncated_vec() {
266        let mut buffer = vec![];
267        buffer.write(&vec32![1u32, 2, 3]).unwrap();
268
269        // Truncate so there's not enough data for all elements
270        let truncated = &buffer[0..8]; // Length prefix + only 1 element
271        let mut src = truncated.to_tape();
272
273        let result = src.read::<Vec32<u32>>();
274        assert!(matches!(result, Err(DecodeError::Exhausted { .. })));
275    }
276
277    #[test]
278    #[cfg(target_pointer_width = "64")]
279    fn test_array_size_overflow() {
280        // Test that writing a string larger than u32::MAX fails
281        let huge_string = "a".repeat(u32::MAX as usize + 1);
282        let mut buffer = vec![];
283
284        let result = buffer.write(&huge_string);
285        assert!(matches!(
286            result,
287            Err(EncodeError::LengthExceedsPrefix { .. })
288        ));
289    }
290
291    #[test]
292    fn test_byte_stream_operations() {
293        let data = [1, 2, 3, 4, 5];
294        let mut src = data.to_tape();
295
296        assert_eq!(src.pos, 0);
297        assert_eq!(src.rest().len(), 5);
298
299        assert_eq!(src.next(), Some(1));
300        assert_eq!(src.pos, 1);
301        assert_eq!(src.rest().len(), 4);
302
303        src.pos += 2;
304        assert_eq!(src.pos, 3);
305        assert_eq!(src.rest().len(), 2);
306
307        assert_eq!(src.next(), Some(4));
308        assert_eq!(src.next(), Some(5));
309        assert_eq!(src.next(), None);
310        assert_eq!(src.rest().len(), 0);
311    }
312
313    #[test]
314    fn test_multiple_values_in_sequence() {
315        let mut buffer = vec![];
316
317        // Write multiple values
318        write_all!(buffer;
319            &42u32,
320            &"hello".to_string(),
321            &true,
322            &vec8![1u8, 2, 3],
323        )
324        .unwrap();
325
326        // Read them back
327        let mut src = buffer.to_tape();
328
329        let num = src.read::<u32>().unwrap();
330        assert_eq!(num, 42);
331
332        let string = src.read::<String>().unwrap();
333        assert_eq!(string, "hello");
334
335        let boolean = src.read::<bool>().unwrap();
336        assert!(boolean);
337
338        let vec = src.read::<Vec8<u8>>().unwrap();
339        assert_eq!(vec.into_inner(), vec![1, 2, 3]);
340
341        assert_eq!(src.rest().len(), 0);
342    }
343
344    #[test]
345    fn test_complex_structure() {
346        // Simulate a complex structure
347        let mut buffer = vec![];
348
349        // Header
350        buffer.write(&0xCAFEBABEu32).unwrap();
351
352        // Version
353        buffer.write(&(1u16, 0u16)).unwrap();
354
355        // Function table
356        let functions = vec32![("main".to_string(), 0u32), ("helper".to_string(), 100u32),];
357        buffer.write(&functions).unwrap();
358
359        // Constants
360        let constants = vec16!["Hello".to_string(), "World".to_string()];
361        buffer.write(&constants).unwrap();
362
363        // Read it all back
364        let mut src = buffer.to_tape();
365
366        let magic = src.read::<u32>().unwrap();
367        assert_eq!(magic, 0xCAFEBABE);
368
369        let version = src.read::<(u16, u16)>().unwrap();
370        assert_eq!(version, (1, 0));
371
372        let funcs = src.read::<Vec32<(String, u32)>>().unwrap();
373        assert_eq!(funcs.len(), 2);
374        assert_eq!(funcs[0].0, "main");
375        assert_eq!(funcs[1].1, 100);
376
377        let consts = src.read::<Vec16<String>>().unwrap();
378        assert_eq!(consts.len(), 2);
379        assert_eq!(consts[0], "Hello");
380
381        assert_eq!(src.rest().len(), 0);
382    }
383
384    #[test]
385    fn test_zero_values() {
386        round_trip(0u8);
387        round_trip(0u16);
388        round_trip(0u32);
389        round_trip(0i8);
390        round_trip(0i16);
391        round_trip(0i32);
392        round_trip(0i64);
393        round_trip(0i128);
394        round_trip(0.0f32);
395        round_trip(0.0f64);
396    }
397
398    #[test]
399    fn test_max_values() {
400        round_trip(u8::MAX);
401        round_trip(u16::MAX);
402        round_trip(u32::MAX);
403        round_trip(i8::MAX);
404        round_trip(i16::MAX);
405        round_trip(i32::MAX);
406        round_trip(i64::MAX);
407        round_trip(i128::MAX);
408    }
409
410    #[test]
411    fn test_min_values() {
412        round_trip(i8::MIN);
413        round_trip(i16::MIN);
414        round_trip(i32::MIN);
415        round_trip(i64::MIN);
416        round_trip(i128::MIN);
417    }
418}