facet_msgpack/
serialize.rs

1use facet_core::Facet;
2use facet_reflect::Peek;
3use facet_serialize::{Serializer, serialize_iterative}; // Import the necessary items from facet-serialize
4use log::trace;
5use std::io::{self, Write};
6
7/// Serializes any Facet type to MessagePack bytes
8pub fn to_vec<'a, T: Facet<'a>>(value: &'a T) -> Vec<u8> {
9    let mut buffer = Vec::new();
10    let peek = Peek::new(value);
11    let mut serializer = MessagePackSerializer {
12        writer: &mut buffer,
13    }; // Create the serializer
14    serialize_iterative(peek, &mut serializer).unwrap(); // Use the iterative serializer
15    buffer
16}
17
18// Define the MessagePackSerializer struct
19struct MessagePackSerializer<'w, W: Write> {
20    writer: &'w mut W,
21}
22
23// Implement the Serializer trait for MessagePackSerializer
24impl<W: Write> Serializer for MessagePackSerializer<'_, W> {
25    type Error = io::Error; // Use io::Error as the error type
26
27    // Implement all methods required by the Serializer trait
28    // Most implementations will simply call the existing write_* helper functions.
29
30    fn serialize_u8(&mut self, value: u8) -> Result<(), Self::Error> {
31        trace!("Serializing u8: {value}");
32        write_u8(self.writer, value)
33    }
34
35    fn serialize_u16(&mut self, value: u16) -> Result<(), Self::Error> {
36        trace!("Serializing u16: {value}");
37        write_u16(self.writer, value)
38    }
39
40    fn serialize_u32(&mut self, value: u32) -> Result<(), Self::Error> {
41        trace!("Serializing u32: {value}");
42        write_u32(self.writer, value)
43    }
44
45    fn serialize_u64(&mut self, value: u64) -> Result<(), Self::Error> {
46        trace!("Serializing u64: {value}");
47        write_u64(self.writer, value)
48    }
49
50    // TODO: Implement serialize_u128 if needed for MessagePack, otherwise return error or panic
51    fn serialize_u128(&mut self, _value: u128) -> Result<(), Self::Error> {
52        Err(io::Error::other(
53            "u128 is not directly supported by MessagePack",
54        ))
55    }
56
57    // Map usize to u64 as MessagePack doesn't have a specific usize type
58    fn serialize_usize(&mut self, value: usize) -> Result<(), Self::Error> {
59        trace!("Serializing usize: {value}");
60        write_u64(self.writer, value as u64) // Assuming usize fits in u64
61    }
62
63    fn serialize_i8(&mut self, value: i8) -> Result<(), Self::Error> {
64        trace!("Serializing i8: {value}");
65        write_i8(self.writer, value)
66    }
67
68    fn serialize_i16(&mut self, value: i16) -> Result<(), Self::Error> {
69        trace!("Serializing i16: {value}");
70        write_i16(self.writer, value)
71    }
72
73    fn serialize_i32(&mut self, value: i32) -> Result<(), Self::Error> {
74        trace!("Serializing i32: {value}");
75        write_i32(self.writer, value)
76    }
77
78    fn serialize_i64(&mut self, value: i64) -> Result<(), Self::Error> {
79        trace!("Serializing i64: {value}");
80        write_i64(self.writer, value)
81    }
82
83    // TODO: Implement serialize_i128 if needed for MessagePack, otherwise return error or panic
84    fn serialize_i128(&mut self, _value: i128) -> Result<(), Self::Error> {
85        Err(io::Error::other(
86            "i128 is not directly supported by MessagePack",
87        ))
88    }
89
90    // Map isize to i64 as MessagePack doesn't have a specific isize type
91    fn serialize_isize(&mut self, value: isize) -> Result<(), Self::Error> {
92        trace!("Serializing isize: {value}");
93        write_i64(self.writer, value as i64) // Assuming isize fits in i64
94    }
95
96    fn serialize_f32(&mut self, value: f32) -> Result<(), Self::Error> {
97        trace!("Serializing f32: {value}");
98        write_f32(self.writer, value)
99    }
100
101    fn serialize_f64(&mut self, value: f64) -> Result<(), Self::Error> {
102        trace!("Serializing f64: {value}");
103        write_f64(self.writer, value)
104    }
105
106    fn serialize_bool(&mut self, value: bool) -> Result<(), Self::Error> {
107        trace!("Serializing bool: {value}");
108        write_bool(self.writer, value)
109    }
110
111    // Characters are often serialized as strings in MessagePack
112    fn serialize_char(&mut self, value: char) -> Result<(), Self::Error> {
113        trace!("Serializing char: {value}");
114        let mut buf = [0; 4];
115        write_str(self.writer, value.encode_utf8(&mut buf))
116    }
117
118    fn serialize_str(&mut self, value: &str) -> Result<(), Self::Error> {
119        trace!("Serializing str: {value}");
120        write_str(self.writer, value)
121    }
122
123    fn serialize_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error> {
124        trace!("Serializing bytes, len: {}", value.len());
125        write_bin(self.writer, value)
126    }
127
128    fn serialize_none(&mut self) -> Result<(), Self::Error> {
129        trace!("Serializing none");
130        write_nil(self.writer)
131    }
132
133    fn serialize_unit(&mut self) -> Result<(), Self::Error> {
134        trace!("Serializing unit");
135        write_nil(self.writer) // Represent unit as nil
136    }
137
138    // Unit variants can be represented as strings or specific codes if needed.
139    // Using string representation for now.
140    fn serialize_unit_variant(
141        &mut self,
142        _variant_index: usize,
143        variant_name: &'static str,
144    ) -> Result<(), Self::Error> {
145        trace!("Serializing unit variant: {variant_name}");
146        write_str(self.writer, variant_name)
147    }
148
149    fn start_object(&mut self, len: Option<usize>) -> Result<(), Self::Error> {
150        trace!("Starting object, len: {len:?}");
151        if let Some(l) = len {
152            write_map_len(self.writer, l)
153        } else {
154            // MessagePack doesn't have an indefinite length map marker.
155            // This might require buffering or a different approach if the length is unknown.
156            // For now, assume length is always known by `facet-serialize`.
157            Err(io::Error::other("MessagePack requires map length upfront"))
158        }
159    }
160
161    fn end_object(&mut self) -> Result<(), Self::Error> {
162        trace!("Ending object");
163        // No explicit end marker needed for fixed-length maps in MessagePack
164        Ok(())
165    }
166
167    fn start_array(&mut self, len: Option<usize>) -> Result<(), Self::Error> {
168        trace!("Starting array, len: {len:?}");
169        if let Some(l) = len {
170            if l == 0 {
171                // In facet's reflection system, unit types `()` are represented as tuples with 0 elements,
172                // which results in empty arrays being serialized. For MessagePack compatibility with
173                // rmp_serde, we serialize empty arrays as nil to match how serde treats unit types.
174                // This ensures consistent behavior between facet-msgpack and rmp_serde.
175                write_nil(self.writer)
176            } else {
177                write_array_len(self.writer, l)
178            }
179        } else {
180            Err(io::Error::other(
181                "MessagePack requires array length upfront",
182            ))
183        }
184    }
185
186    fn end_array(&mut self) -> Result<(), Self::Error> {
187        trace!("Ending array");
188        // No explicit end marker needed for fixed-length arrays in MessagePack
189        Ok(())
190    }
191
192    // Maps in facet-serialize correspond to MessagePack maps
193    fn start_map(&mut self, len: Option<usize>) -> Result<(), Self::Error> {
194        trace!("Starting map, len: {len:?}");
195        if let Some(l) = len {
196            write_map_len(self.writer, l)
197        } else {
198            Err(io::Error::other("MessagePack requires map length upfront"))
199        }
200    }
201
202    fn end_map(&mut self) -> Result<(), Self::Error> {
203        trace!("Ending map");
204        // No explicit end marker needed for fixed-length maps in MessagePack
205        Ok(())
206    }
207
208    // Field names are serialized as strings (keys) in MessagePack maps
209    fn serialize_field_name(&mut self, name: &'static str) -> Result<(), Self::Error> {
210        trace!("Serializing field name: {name}");
211        write_str(self.writer, name)
212    }
213}
214
215fn write_nil<W: Write>(writer: &mut W) -> io::Result<()> {
216    writer.write_all(&[0xc0])
217}
218
219fn write_bool<W: Write>(writer: &mut W, val: bool) -> io::Result<()> {
220    if val {
221        writer.write_all(&[0xc3]) // true
222    } else {
223        writer.write_all(&[0xc2]) // false
224    }
225}
226
227fn write_f32<W: Write>(writer: &mut W, n: f32) -> io::Result<()> {
228    writer.write_all(&[0xca])?; // float 32
229    writer.write_all(&n.to_be_bytes())
230}
231
232fn write_f64<W: Write>(writer: &mut W, n: f64) -> io::Result<()> {
233    writer.write_all(&[0xcb])?; // float 64
234    writer.write_all(&n.to_be_bytes())
235}
236
237fn write_bin<W: Write>(writer: &mut W, bytes: &[u8]) -> io::Result<()> {
238    let len = bytes.len();
239    match len {
240        0..=255 => {
241            // bin 8
242            writer.write_all(&[0xc4, len as u8])?;
243        }
244        256..=65535 => {
245            // bin 16
246            writer.write_all(&[0xc5])?;
247            writer.write_all(&(len as u16).to_be_bytes())?;
248        }
249        _ => {
250            // bin 32
251            writer.write_all(&[0xc6])?;
252            writer.write_all(&(len as u32).to_be_bytes())?;
253        }
254    }
255    writer.write_all(bytes)
256}
257
258fn write_array_len<W: Write>(writer: &mut W, len: usize) -> io::Result<()> {
259    match len {
260        0..=15 => {
261            // fixarray
262            writer.write_all(&[(0x90 | len as u8)])
263        }
264        16..=65535 => {
265            // array 16
266            writer.write_all(&[0xdc])?;
267            writer.write_all(&(len as u16).to_be_bytes())
268        }
269        _ => {
270            // array 32
271            writer.write_all(&[0xdd])?;
272            writer.write_all(&(len as u32).to_be_bytes())
273        }
274    }
275}
276
277// --- Existing write_* functions from the original file ---
278// (write_str, write_u8, write_u16, write_u32, write_u64, write_i8, write_i16, write_i32, write_i64, write_map_len)
279// These remain largely unchanged.
280
281fn write_str<W: Write>(writer: &mut W, s: &str) -> io::Result<()> {
282    let bytes = s.as_bytes();
283    let len = bytes.len();
284
285    match len {
286        0..=31 => {
287            // fixstr
288            writer.write_all(&[(0xa0 | len as u8)])?;
289        }
290        32..=255 => {
291            // str8
292            writer.write_all(&[0xd9, len as u8])?;
293        }
294        256..=65535 => {
295            // str16
296            writer.write_all(&[0xda])?;
297            writer.write_all(&(len as u16).to_be_bytes())?;
298        }
299        _ => {
300            // str32
301            writer.write_all(&[0xdb])?;
302            writer.write_all(&(len as u32).to_be_bytes())?;
303        }
304    }
305    writer.write_all(bytes)
306}
307
308fn write_u8<W: Write>(writer: &mut W, n: u8) -> io::Result<()> {
309    match n {
310        0..=127 => {
311            // positive fixint
312            writer.write_all(&[n])
313        }
314        _ => {
315            // uint8
316            writer.write_all(&[0xcc, n])
317        }
318    }
319}
320
321fn write_u16<W: Write>(writer: &mut W, n: u16) -> io::Result<()> {
322    match n {
323        0..=127 => {
324            // positive fixint
325            writer.write_all(&[n as u8])
326        }
327        128..=255 => {
328            // uint8
329            writer.write_all(&[0xcc, n as u8])
330        }
331        _ => {
332            // uint16
333            writer.write_all(&[0xcd])?;
334            writer.write_all(&n.to_be_bytes())
335        }
336    }
337}
338
339fn write_u32<W: Write>(writer: &mut W, n: u32) -> io::Result<()> {
340    match n {
341        0..=127 => {
342            // positive fixint
343            writer.write_all(&[n as u8])
344        }
345        128..=255 => {
346            // uint8
347            writer.write_all(&[0xcc, n as u8])
348        }
349        256..=65535 => {
350            // uint16
351            writer.write_all(&[0xcd])?;
352            writer.write_all(&(n as u16).to_be_bytes())
353        }
354        _ => {
355            // uint32
356            writer.write_all(&[0xce])?;
357            writer.write_all(&n.to_be_bytes())
358        }
359    }
360}
361
362fn write_u64<W: Write>(writer: &mut W, n: u64) -> io::Result<()> {
363    match n {
364        0..=127 => {
365            // positive fixint
366            writer.write_all(&[n as u8])
367        }
368        128..=255 => {
369            // uint8
370            writer.write_all(&[0xcc, n as u8])
371        }
372        256..=65535 => {
373            // uint16
374            writer.write_all(&[0xcd])?;
375            writer.write_all(&(n as u16).to_be_bytes())
376        }
377        65536..=4294967295 => {
378            // uint32
379            writer.write_all(&[0xce])?;
380            writer.write_all(&(n as u32).to_be_bytes())
381        }
382        _ => {
383            // uint64
384            writer.write_all(&[0xcf])?;
385            writer.write_all(&n.to_be_bytes())
386        }
387    }
388}
389
390fn write_i8<W: Write>(writer: &mut W, n: i8) -> io::Result<()> {
391    match n {
392        -32..=-1 => {
393            // negative fixint
394            writer.write_all(&[n as u8])
395        }
396        -128..=-33 => {
397            // int8
398            writer.write_all(&[0xd0, n as u8])
399        }
400        0..=127 => {
401            // positive fixint or uint8
402            write_u8(writer, n as u8) // Reuse u8 logic for positive values
403        }
404    }
405}
406
407fn write_i16<W: Write>(writer: &mut W, n: i16) -> io::Result<()> {
408    match n {
409        -32..=-1 => {
410            // negative fixint
411            writer.write_all(&[n as u8])
412        }
413        -128..=-33 => {
414            // int8
415            writer.write_all(&[0xd0, n as u8])
416        }
417        -32768..=-129 => {
418            // int16
419            writer.write_all(&[0xd1])?;
420            writer.write_all(&n.to_be_bytes())
421        }
422        0..=32767 => {
423            // Use unsigned logic for positive range
424            write_u16(writer, n as u16)
425        }
426    }
427}
428
429fn write_i32<W: Write>(writer: &mut W, n: i32) -> io::Result<()> {
430    match n {
431        -32..=-1 => {
432            // negative fixint
433            writer.write_all(&[n as u8])
434        }
435        -128..=-33 => {
436            // int8
437            writer.write_all(&[0xd0, n as u8])
438        }
439        -32768..=-129 => {
440            // int16
441            writer.write_all(&[0xd1])?;
442            writer.write_all(&(n as i16).to_be_bytes())
443        }
444        -2147483648..=-32769 => {
445            // int32
446            writer.write_all(&[0xd2])?;
447            writer.write_all(&n.to_be_bytes())
448        }
449        0..=2147483647 => {
450            // Use unsigned logic for positive range
451            write_u32(writer, n as u32)
452        }
453    }
454}
455
456fn write_i64<W: Write>(writer: &mut W, n: i64) -> io::Result<()> {
457    match n {
458        -32..=-1 => {
459            // negative fixint
460            writer.write_all(&[n as u8])
461        }
462        -128..=-33 => {
463            // int8
464            writer.write_all(&[0xd0, n as u8])
465        }
466        -32768..=-129 => {
467            // int16
468            writer.write_all(&[0xd1])?;
469            writer.write_all(&(n as i16).to_be_bytes())
470        }
471        -2147483648..=-32769 => {
472            // int32
473            writer.write_all(&[0xd2])?;
474            writer.write_all(&(n as i32).to_be_bytes())
475        }
476        i64::MIN..=-2147483649 => {
477            // int64
478            writer.write_all(&[0xd3])?;
479            writer.write_all(&n.to_be_bytes())
480        }
481        0..=i64::MAX => {
482            // Use unsigned logic for positive range
483            write_u64(writer, n as u64)
484        }
485    }
486}
487
488fn write_map_len<W: Write>(writer: &mut W, len: usize) -> io::Result<()> {
489    match len {
490        0..=15 => {
491            // fixmap
492            writer.write_all(&[(0x80 | len as u8)])
493        }
494        16..=65535 => {
495            // map16
496            writer.write_all(&[0xde])?;
497            writer.write_all(&(len as u16).to_be_bytes())
498        }
499        _ => {
500            // map32
501            writer.write_all(&[0xdf])?;
502            writer.write_all(&(len as u32).to_be_bytes())
503        }
504    }
505}
506
507#[cfg(test)]
508mod tests {
509    use super::*;
510    use facet::Facet;
511    use serde::Serialize; // Import serde::Serialize
512
513    // Helper function to serialize with rmp_serde
514    fn rmp_serialize<T: Serialize>(value: &T) -> Vec<u8> {
515        // Configure rmp_serde to serialize structs as maps
516        let mut buf = Vec::new();
517        let mut ser = rmp_serde::Serializer::new(&mut buf)
518            .with_bytes(rmp_serde::config::BytesMode::ForceIterables)
519            .with_struct_map();
520        value.serialize(&mut ser).unwrap();
521        buf
522    }
523
524    #[derive(Facet, Serialize, PartialEq, Debug)] // Add Serialize
525    struct SimpleStruct {
526        a: u32,
527        b: String,
528        c: bool,
529    }
530
531    #[test]
532    fn test_simple_struct() {
533        let value = SimpleStruct {
534            a: 123,
535            b: "hello".to_string(),
536            c: true,
537        };
538
539        let facet_bytes = to_vec(&value);
540        let rmp_bytes = rmp_serialize(&value);
541
542        assert_eq!(facet_bytes, rmp_bytes);
543    }
544
545    #[derive(Facet, Serialize, PartialEq, Debug)] // Add Serialize
546    struct NestedStruct {
547        inner: SimpleStruct,
548        d: Option<i8>,
549        e: Vec<u8>,
550    }
551
552    #[test]
553    fn test_nested_struct() {
554        let value = NestedStruct {
555            inner: SimpleStruct {
556                a: 456,
557                b: "world".to_string(),
558                c: false,
559            },
560            d: Some(-5),
561            e: vec![1, 2, 3, 4, 5],
562        };
563
564        let facet_bytes = to_vec(&value);
565        let rmp_bytes = rmp_serialize(&value);
566
567        assert_eq!(facet_bytes, rmp_bytes);
568    }
569
570    #[test]
571    fn test_nested_struct_none() {
572        let value = NestedStruct {
573            inner: SimpleStruct {
574                a: 789,
575                b: "another".to_string(),
576                c: true,
577            },
578            d: None,
579            e: vec![0], // rmp can't serialize empty bin8 correctly
580        };
581
582        let facet_bytes = to_vec(&value);
583        let rmp_bytes = rmp_serialize(&value);
584
585        assert_eq!(facet_bytes, rmp_bytes);
586    }
587
588    #[derive(Facet, Serialize, PartialEq, Debug)] // Add Serialize
589    #[repr(u8)]
590    #[allow(dead_code)]
591    enum TestEnum {
592        Unit,
593        Tuple(u32, String),
594        Struct { name: String, value: i64 },
595    }
596
597    #[test]
598    fn test_enum_unit() {
599        let value = TestEnum::Unit;
600        let facet_bytes = to_vec(&value);
601        // rmp-serde serializes unit variants as just the string name
602        let rmp_bytes = rmp_serialize(&"Unit");
603        assert_eq!(facet_bytes, rmp_bytes);
604    }
605
606    #[test]
607    fn test_f32() {
608        #[derive(Facet, Serialize, PartialEq, Debug)]
609        struct FloatStruct {
610            value: f32,
611        }
612
613        let value = FloatStruct { value: 1.23 };
614        let facet_bytes = to_vec(&value);
615        let rmp_bytes = rmp_serialize(&value);
616        assert_eq!(facet_bytes, rmp_bytes);
617    }
618
619    #[test]
620    fn test_f64() {
621        #[derive(Facet, Serialize, PartialEq, Debug)]
622        struct DoubleStruct {
623            value: f64,
624        }
625
626        let value = DoubleStruct { value: -4.56e7 };
627        let facet_bytes = to_vec(&value);
628        let rmp_bytes = rmp_serialize(&value);
629        assert_eq!(facet_bytes, rmp_bytes);
630    }
631
632    #[test]
633    fn test_i8() {
634        #[derive(Facet, Serialize, PartialEq, Debug)]
635        struct I8Struct {
636            value: i8,
637        }
638
639        let value = I8Struct { value: -10 };
640        let facet_bytes = to_vec(&value);
641        let rmp_bytes = rmp_serialize(&value);
642        assert_eq!(facet_bytes, rmp_bytes);
643    }
644
645    #[test]
646    fn test_i16() {
647        #[derive(Facet, Serialize, PartialEq, Debug)]
648        struct I16Struct {
649            value: i16,
650        }
651
652        let value = I16Struct { value: -1000 };
653        let facet_bytes = to_vec(&value);
654        let rmp_bytes = rmp_serialize(&value);
655        assert_eq!(facet_bytes, rmp_bytes);
656    }
657
658    #[test]
659    fn test_i32() {
660        #[derive(Facet, Serialize, PartialEq, Debug)]
661        struct I32Struct {
662            value: i32,
663        }
664
665        let value = I32Struct { value: -100000 };
666        let facet_bytes = to_vec(&value);
667        let rmp_bytes = rmp_serialize(&value);
668        assert_eq!(facet_bytes, rmp_bytes);
669    }
670
671    #[test]
672    fn test_i64() {
673        #[derive(Facet, Serialize, PartialEq, Debug)]
674        struct I64Struct {
675            value: i64,
676        }
677
678        let value = I64Struct {
679            value: -10000000000,
680        };
681        let facet_bytes = to_vec(&value);
682        let rmp_bytes = rmp_serialize(&value);
683        assert_eq!(facet_bytes, rmp_bytes);
684    }
685
686    #[test]
687    fn test_u8() {
688        #[derive(Facet, Serialize, PartialEq, Debug)]
689        struct U8Struct {
690            value: u8,
691        }
692
693        let value = U8Struct { value: 10 };
694        let facet_bytes = to_vec(&value);
695        let rmp_bytes = rmp_serialize(&value);
696        assert_eq!(facet_bytes, rmp_bytes);
697    }
698
699    #[test]
700    fn test_u16() {
701        #[derive(Facet, Serialize, PartialEq, Debug)]
702        struct U16Struct {
703            value: u16,
704        }
705
706        let value = U16Struct { value: 1000 };
707        let facet_bytes = to_vec(&value);
708        let rmp_bytes = rmp_serialize(&value);
709        assert_eq!(facet_bytes, rmp_bytes);
710    }
711
712    #[test]
713    fn test_u32() {
714        #[derive(Facet, Serialize, PartialEq, Debug)]
715        struct U32Struct {
716            value: u32,
717        }
718
719        let value = U32Struct { value: 100000 };
720        let facet_bytes = to_vec(&value);
721        let rmp_bytes = rmp_serialize(&value);
722        assert_eq!(facet_bytes, rmp_bytes);
723    }
724
725    #[test]
726    fn test_u64() {
727        #[derive(Facet, Serialize, PartialEq, Debug)]
728        struct U64Struct {
729            value: u64,
730        }
731
732        let value = U64Struct { value: 10000000000 };
733        let facet_bytes = to_vec(&value);
734        let rmp_bytes = rmp_serialize(&value);
735        assert_eq!(facet_bytes, rmp_bytes);
736    }
737
738    #[test]
739    fn test_bytes() {
740        #[derive(Facet, Serialize, PartialEq, Debug)]
741        struct BytesStruct {
742            value: Vec<u8>,
743        }
744
745        let value = BytesStruct {
746            value: b"binary data".to_vec(),
747        };
748        let facet_bytes = to_vec(&value);
749        let rmp_bytes = rmp_serialize(&value);
750        assert_eq!(facet_bytes, rmp_bytes);
751    }
752
753    #[test]
754    fn test_string() {
755        #[derive(Facet, Serialize, PartialEq, Debug)]
756        struct StringStruct {
757            value: String,
758        }
759
760        let value = StringStruct {
761            value: "string data".to_string(),
762        };
763        let facet_bytes = to_vec(&value);
764        let rmp_bytes = rmp_serialize(&value);
765        assert_eq!(facet_bytes, rmp_bytes);
766    }
767
768    #[test]
769    fn test_char() {
770        #[derive(Facet, Serialize, PartialEq, Debug)]
771        struct CharStruct {
772            value: char,
773        }
774
775        let value = CharStruct { value: '✅' };
776        let facet_bytes = to_vec(&value);
777        let rmp_bytes = rmp_serialize(&value);
778        assert_eq!(facet_bytes, rmp_bytes);
779    }
780
781    #[test]
782    fn test_option_some() {
783        #[derive(Facet, Serialize, PartialEq, Debug)]
784        struct OptionSomeStruct {
785            value: Option<i32>,
786        }
787
788        let value = OptionSomeStruct { value: Some(99) };
789        let facet_bytes = to_vec(&value);
790        let rmp_bytes = rmp_serialize(&value);
791        assert_eq!(facet_bytes, rmp_bytes);
792    }
793
794    #[test]
795    fn test_option_none() {
796        #[derive(Facet, Serialize, PartialEq, Debug)]
797        struct OptionNoneStruct {
798            value: Option<String>,
799        }
800
801        let value = OptionNoneStruct { value: None };
802        let facet_bytes = to_vec(&value);
803        let rmp_bytes = rmp_serialize(&value);
804        assert_eq!(facet_bytes, rmp_bytes);
805    }
806
807    #[test]
808    fn test_unit() {
809        #[derive(Facet, Serialize, PartialEq, Debug)]
810        struct UnitStruct {
811            value: (),
812        }
813
814        let value = UnitStruct { value: () };
815        let facet_bytes = to_vec(&value);
816        let rmp_bytes = rmp_serialize(&value);
817        assert_eq!(facet_bytes, rmp_bytes);
818    }
819
820    #[test]
821    fn test_empty_vec() {
822        #[derive(Facet, Serialize, PartialEq, Debug)]
823        struct EmptyVecStruct {
824            value: Vec<i32>,
825        }
826
827        let value = EmptyVecStruct { value: vec![] };
828        let facet_bytes = to_vec(&value);
829
830        // Empty collections are serialized as nil in facet-msgpack to maintain consistency
831        // with how unit types are handled. This ensures uniform behavior for "empty" values.
832        let expected = vec![0x81, 0xa5, b'v', b'a', b'l', b'u', b'e', 0xc0]; // map with "value" -> nil
833        assert_eq!(facet_bytes, expected);
834    }
835}