facet_msgpack/
serialize.rs

1use facet_core::{Def, Facet, StructKind, Type, UserType};
2use facet_reflect::{HasFields, Peek, ScalarType};
3use log::trace;
4use std::io::{self, Write};
5
6/// Serializes any Facet type to MessagePack bytes
7pub fn to_vec<T: Facet<'static>>(value: &T) -> Vec<u8> {
8    let mut buffer = Vec::new();
9    to_writer(&mut buffer, value).unwrap();
10    buffer
11}
12
13/// Serializes any Facet type to MessagePack bytes, writing to the given writer
14pub fn to_writer<T: Facet<'static>, W: Write>(writer: &mut W, value: &T) -> io::Result<()> {
15    let peek = Peek::new(value);
16    serialize_value(peek, writer)
17}
18
19fn serialize_value<W: Write>(peek: Peek<'_, '_>, writer: &mut W) -> io::Result<()> {
20    trace!("Serializing value, shape is {}", peek.shape());
21
22    match (peek.shape().def, peek.shape().ty) {
23        (Def::Scalar, _) => {
24            let peek = peek.innermost_peek();
25            serialize_scalar(peek, writer)
26        }
27        (Def::List(ld), _) => {
28            // Special case for Vec<u8> - serialize as binary
29            if ld.t().is_type::<u8>() && peek.shape().is_type::<Vec<u8>>() {
30                let bytes = peek.get::<Vec<u8>>().unwrap();
31                write_bin(writer, bytes)
32            } else {
33                let list = peek.into_list_like().unwrap();
34                let items: Vec<_> = list.iter().collect();
35                serialize_array(items, writer)
36            }
37        }
38        (Def::Array(ad), _) => {
39            if ad.t().is_type::<u8>() {
40                // Collect bytes from array
41                let bytes: Vec<u8> = peek
42                    .into_list_like()
43                    .unwrap()
44                    .iter()
45                    .map(|p| *p.get::<u8>().unwrap())
46                    .collect();
47                write_bin(writer, &bytes)
48            } else {
49                let list = peek.into_list_like().unwrap();
50                let items: Vec<_> = list.iter().collect();
51                serialize_array(items, writer)
52            }
53        }
54        (Def::Slice(sd), _) => {
55            if sd.t().is_type::<u8>() {
56                let bytes = peek.get::<[u8]>().unwrap();
57                write_bin(writer, bytes)
58            } else {
59                let list = peek.into_list_like().unwrap();
60                let items: Vec<_> = list.iter().collect();
61                serialize_array(items, writer)
62            }
63        }
64        (Def::Map(_), _) => {
65            let map = peek.into_map().unwrap();
66            let entries: Vec<_> = map.iter().collect();
67            write_map_len(writer, entries.len())?;
68            for (key, value) in entries {
69                serialize_value(key, writer)?;
70                serialize_value(value, writer)?;
71            }
72            Ok(())
73        }
74        (Def::Set(_), _) => {
75            let set = peek.into_set().unwrap();
76            let items: Vec<_> = set.iter().collect();
77            serialize_array(items, writer)
78        }
79        (Def::Option(_), _) => {
80            let opt = peek.into_option().unwrap();
81            if let Some(inner) = opt.value() {
82                serialize_value(inner, writer)
83            } else {
84                write_nil(writer)
85            }
86        }
87        (Def::Pointer(_), _) => {
88            let ptr = peek.into_pointer().unwrap();
89            if let Some(inner) = ptr.borrow_inner() {
90                serialize_value(inner, writer)
91            } else {
92                Err(io::Error::other(
93                    "Smart pointer without borrow support cannot be serialized",
94                ))
95            }
96        }
97        (_, Type::User(UserType::Struct(sd))) => {
98            match sd.kind {
99                StructKind::Unit => {
100                    // Unit structs serialize as nil
101                    write_nil(writer)
102                }
103                StructKind::Tuple => {
104                    let ps = peek.into_struct().unwrap();
105                    let fields: Vec<_> = ps.fields().map(|(_, v)| v).collect();
106                    if fields.is_empty() {
107                        // Empty tuple (unit type) -> nil for rmp_serde compatibility
108                        write_nil(writer)
109                    } else {
110                        write_array_len(writer, fields.len())?;
111                        for field_value in fields {
112                            serialize_value(field_value, writer)?;
113                        }
114                        Ok(())
115                    }
116                }
117                StructKind::TupleStruct => {
118                    let ps = peek.into_struct().unwrap();
119                    let fields: Vec<_> = ps.fields_for_serialize().collect();
120                    write_array_len(writer, fields.len())?;
121                    for (_, field_value) in fields {
122                        serialize_value(field_value, writer)?;
123                    }
124                    Ok(())
125                }
126                StructKind::Struct => {
127                    let ps = peek.into_struct().unwrap();
128                    let fields: Vec<_> = ps.fields_for_serialize().collect();
129                    write_map_len(writer, fields.len())?;
130                    for (field, field_value) in fields {
131                        write_str(writer, field.name)?;
132                        serialize_value(field_value, writer)?;
133                    }
134                    Ok(())
135                }
136            }
137        }
138        (_, Type::User(UserType::Enum(_))) => {
139            let pe = peek.into_enum().unwrap();
140            let variant = pe.active_variant().expect("Failed to get active variant");
141            trace!("Serializing enum variant: {}", variant.name);
142
143            if variant.data.fields.is_empty() {
144                // Unit variant - just the name as a string
145                write_str(writer, variant.name)
146            } else if variant.data.kind == StructKind::Tuple && variant.data.fields.len() == 1 {
147                // Newtype variant - serialize as {"VariantName": inner_value}
148                write_map_len(writer, 1)?;
149                write_str(writer, variant.name)?;
150                let fields: Vec<_> = pe.fields_for_serialize().collect();
151                serialize_value(fields[0].1, writer)
152            } else if variant.data.kind == StructKind::Tuple
153                || variant.data.kind == StructKind::TupleStruct
154            {
155                // Tuple variant - serialize as {"VariantName": [values...]}
156                write_map_len(writer, 1)?;
157                write_str(writer, variant.name)?;
158                let fields: Vec<_> = pe.fields_for_serialize().collect();
159                write_array_len(writer, fields.len())?;
160                for (_, field_value) in fields {
161                    serialize_value(field_value, writer)?;
162                }
163                Ok(())
164            } else {
165                // Struct variant - serialize as {"VariantName": {fields...}}
166                write_map_len(writer, 1)?;
167                write_str(writer, variant.name)?;
168                let fields: Vec<_> = pe.fields_for_serialize().collect();
169                write_map_len(writer, fields.len())?;
170                for (field, field_value) in fields {
171                    write_str(writer, field.name)?;
172                    serialize_value(field_value, writer)?;
173                }
174                Ok(())
175            }
176        }
177        (_, Type::Pointer(_)) => {
178            // Handle string types
179            if let Some(s) = peek.as_str() {
180                write_str(writer, s)
181            } else if let Some(bytes) = peek.as_bytes() {
182                write_bin(writer, bytes)
183            } else {
184                let innermost = peek.innermost_peek();
185                if innermost.shape() != peek.shape() {
186                    serialize_value(innermost, writer)
187                } else {
188                    write_nil(writer)
189                }
190            }
191        }
192        _ => {
193            trace!("Unhandled type: {:?}, serializing as nil", peek.shape().ty);
194            write_nil(writer)
195        }
196    }
197}
198
199fn serialize_scalar<W: Write>(peek: Peek<'_, '_>, writer: &mut W) -> io::Result<()> {
200    match peek.scalar_type() {
201        Some(ScalarType::Unit) => write_nil(writer),
202        Some(ScalarType::Bool) => {
203            let v = *peek.get::<bool>().unwrap();
204            write_bool(writer, v)
205        }
206        Some(ScalarType::Char) => {
207            let c = *peek.get::<char>().unwrap();
208            let mut buf = [0; 4];
209            write_str(writer, c.encode_utf8(&mut buf))
210        }
211        Some(ScalarType::Str) => write_str(writer, peek.get::<str>().unwrap()),
212        Some(ScalarType::String) => write_str(writer, peek.get::<String>().unwrap()),
213        Some(ScalarType::CowStr) => {
214            write_str(writer, peek.get::<std::borrow::Cow<'_, str>>().unwrap())
215        }
216        Some(ScalarType::F32) => {
217            let v = *peek.get::<f32>().unwrap();
218            write_f32(writer, v)
219        }
220        Some(ScalarType::F64) => {
221            let v = *peek.get::<f64>().unwrap();
222            write_f64(writer, v)
223        }
224        Some(ScalarType::U8) => {
225            let v = *peek.get::<u8>().unwrap();
226            write_u8(writer, v)
227        }
228        Some(ScalarType::U16) => {
229            let v = *peek.get::<u16>().unwrap();
230            write_u16(writer, v)
231        }
232        Some(ScalarType::U32) => {
233            let v = *peek.get::<u32>().unwrap();
234            write_u32(writer, v)
235        }
236        Some(ScalarType::U64) => {
237            let v = *peek.get::<u64>().unwrap();
238            write_u64(writer, v)
239        }
240        Some(ScalarType::U128) => Err(io::Error::other(
241            "u128 is not directly supported by MessagePack",
242        )),
243        Some(ScalarType::USize) => {
244            let v = *peek.get::<usize>().unwrap();
245            write_u64(writer, v as u64)
246        }
247        Some(ScalarType::I8) => {
248            let v = *peek.get::<i8>().unwrap();
249            write_i8(writer, v)
250        }
251        Some(ScalarType::I16) => {
252            let v = *peek.get::<i16>().unwrap();
253            write_i16(writer, v)
254        }
255        Some(ScalarType::I32) => {
256            let v = *peek.get::<i32>().unwrap();
257            write_i32(writer, v)
258        }
259        Some(ScalarType::I64) => {
260            let v = *peek.get::<i64>().unwrap();
261            write_i64(writer, v)
262        }
263        Some(ScalarType::I128) => Err(io::Error::other(
264            "i128 is not directly supported by MessagePack",
265        )),
266        Some(ScalarType::ISize) => {
267            let v = *peek.get::<isize>().unwrap();
268            write_i64(writer, v as i64)
269        }
270        Some(other) => Err(io::Error::other(format!(
271            "Unsupported scalar type: {other:?}"
272        ))),
273        None => Err(io::Error::other(format!(
274            "Unknown scalar shape: {}",
275            peek.shape()
276        ))),
277    }
278}
279
280fn serialize_array<W: Write>(items: Vec<Peek<'_, '_>>, writer: &mut W) -> io::Result<()> {
281    if items.is_empty() {
282        // Empty arrays serialize as nil for rmp_serde compatibility
283        write_nil(writer)
284    } else {
285        write_array_len(writer, items.len())?;
286        for item in items {
287            serialize_value(item, writer)?;
288        }
289        Ok(())
290    }
291}
292
293// --- MessagePack encoding functions ---
294
295fn write_nil<W: Write>(writer: &mut W) -> io::Result<()> {
296    writer.write_all(&[0xc0])
297}
298
299fn write_bool<W: Write>(writer: &mut W, val: bool) -> io::Result<()> {
300    if val {
301        writer.write_all(&[0xc3]) // true
302    } else {
303        writer.write_all(&[0xc2]) // false
304    }
305}
306
307fn write_f32<W: Write>(writer: &mut W, n: f32) -> io::Result<()> {
308    writer.write_all(&[0xca])?; // float 32
309    writer.write_all(&n.to_be_bytes())
310}
311
312fn write_f64<W: Write>(writer: &mut W, n: f64) -> io::Result<()> {
313    writer.write_all(&[0xcb])?; // float 64
314    writer.write_all(&n.to_be_bytes())
315}
316
317fn write_bin<W: Write>(writer: &mut W, bytes: &[u8]) -> io::Result<()> {
318    let len = bytes.len();
319    match len {
320        0..=255 => {
321            // bin 8
322            writer.write_all(&[0xc4, len as u8])?;
323        }
324        256..=65535 => {
325            // bin 16
326            writer.write_all(&[0xc5])?;
327            writer.write_all(&(len as u16).to_be_bytes())?;
328        }
329        _ => {
330            // bin 32
331            writer.write_all(&[0xc6])?;
332            writer.write_all(&(len as u32).to_be_bytes())?;
333        }
334    }
335    writer.write_all(bytes)
336}
337
338fn write_array_len<W: Write>(writer: &mut W, len: usize) -> io::Result<()> {
339    match len {
340        0..=15 => {
341            // fixarray
342            writer.write_all(&[(0x90 | len as u8)])
343        }
344        16..=65535 => {
345            // array 16
346            writer.write_all(&[0xdc])?;
347            writer.write_all(&(len as u16).to_be_bytes())
348        }
349        _ => {
350            // array 32
351            writer.write_all(&[0xdd])?;
352            writer.write_all(&(len as u32).to_be_bytes())
353        }
354    }
355}
356
357fn write_str<W: Write>(writer: &mut W, s: &str) -> io::Result<()> {
358    let bytes = s.as_bytes();
359    let len = bytes.len();
360
361    match len {
362        0..=31 => {
363            // fixstr
364            writer.write_all(&[(0xa0 | len as u8)])?;
365        }
366        32..=255 => {
367            // str8
368            writer.write_all(&[0xd9, len as u8])?;
369        }
370        256..=65535 => {
371            // str16
372            writer.write_all(&[0xda])?;
373            writer.write_all(&(len as u16).to_be_bytes())?;
374        }
375        _ => {
376            // str32
377            writer.write_all(&[0xdb])?;
378            writer.write_all(&(len as u32).to_be_bytes())?;
379        }
380    }
381    writer.write_all(bytes)
382}
383
384fn write_u8<W: Write>(writer: &mut W, n: u8) -> io::Result<()> {
385    match n {
386        0..=127 => {
387            // positive fixint
388            writer.write_all(&[n])
389        }
390        _ => {
391            // uint8
392            writer.write_all(&[0xcc, n])
393        }
394    }
395}
396
397fn write_u16<W: Write>(writer: &mut W, n: u16) -> io::Result<()> {
398    match n {
399        0..=127 => {
400            // positive fixint
401            writer.write_all(&[n as u8])
402        }
403        128..=255 => {
404            // uint8
405            writer.write_all(&[0xcc, n as u8])
406        }
407        _ => {
408            // uint16
409            writer.write_all(&[0xcd])?;
410            writer.write_all(&n.to_be_bytes())
411        }
412    }
413}
414
415fn write_u32<W: Write>(writer: &mut W, n: u32) -> io::Result<()> {
416    match n {
417        0..=127 => {
418            // positive fixint
419            writer.write_all(&[n as u8])
420        }
421        128..=255 => {
422            // uint8
423            writer.write_all(&[0xcc, n as u8])
424        }
425        256..=65535 => {
426            // uint16
427            writer.write_all(&[0xcd])?;
428            writer.write_all(&(n as u16).to_be_bytes())
429        }
430        _ => {
431            // uint32
432            writer.write_all(&[0xce])?;
433            writer.write_all(&n.to_be_bytes())
434        }
435    }
436}
437
438fn write_u64<W: Write>(writer: &mut W, n: u64) -> io::Result<()> {
439    match n {
440        0..=127 => {
441            // positive fixint
442            writer.write_all(&[n as u8])
443        }
444        128..=255 => {
445            // uint8
446            writer.write_all(&[0xcc, n as u8])
447        }
448        256..=65535 => {
449            // uint16
450            writer.write_all(&[0xcd])?;
451            writer.write_all(&(n as u16).to_be_bytes())
452        }
453        65536..=4294967295 => {
454            // uint32
455            writer.write_all(&[0xce])?;
456            writer.write_all(&(n as u32).to_be_bytes())
457        }
458        _ => {
459            // uint64
460            writer.write_all(&[0xcf])?;
461            writer.write_all(&n.to_be_bytes())
462        }
463    }
464}
465
466fn write_i8<W: Write>(writer: &mut W, n: i8) -> io::Result<()> {
467    match n {
468        -32..=-1 => {
469            // negative fixint
470            writer.write_all(&[n as u8])
471        }
472        -128..=-33 => {
473            // int8
474            writer.write_all(&[0xd0, n as u8])
475        }
476        0..=127 => {
477            // positive fixint or uint8
478            write_u8(writer, n as u8)
479        }
480    }
481}
482
483fn write_i16<W: Write>(writer: &mut W, n: i16) -> io::Result<()> {
484    match n {
485        -32..=-1 => {
486            // negative fixint
487            writer.write_all(&[n as u8])
488        }
489        -128..=-33 => {
490            // int8
491            writer.write_all(&[0xd0, n as u8])
492        }
493        -32768..=-129 => {
494            // int16
495            writer.write_all(&[0xd1])?;
496            writer.write_all(&n.to_be_bytes())
497        }
498        0..=32767 => {
499            // Use unsigned logic for positive range
500            write_u16(writer, n as u16)
501        }
502    }
503}
504
505fn write_i32<W: Write>(writer: &mut W, n: i32) -> io::Result<()> {
506    match n {
507        -32..=-1 => {
508            // negative fixint
509            writer.write_all(&[n as u8])
510        }
511        -128..=-33 => {
512            // int8
513            writer.write_all(&[0xd0, n as u8])
514        }
515        -32768..=-129 => {
516            // int16
517            writer.write_all(&[0xd1])?;
518            writer.write_all(&(n as i16).to_be_bytes())
519        }
520        -2147483648..=-32769 => {
521            // int32
522            writer.write_all(&[0xd2])?;
523            writer.write_all(&n.to_be_bytes())
524        }
525        0..=2147483647 => {
526            // Use unsigned logic for positive range
527            write_u32(writer, n as u32)
528        }
529    }
530}
531
532fn write_i64<W: Write>(writer: &mut W, n: i64) -> io::Result<()> {
533    match n {
534        -32..=-1 => {
535            // negative fixint
536            writer.write_all(&[n as u8])
537        }
538        -128..=-33 => {
539            // int8
540            writer.write_all(&[0xd0, n as u8])
541        }
542        -32768..=-129 => {
543            // int16
544            writer.write_all(&[0xd1])?;
545            writer.write_all(&(n as i16).to_be_bytes())
546        }
547        -2147483648..=-32769 => {
548            // int32
549            writer.write_all(&[0xd2])?;
550            writer.write_all(&(n as i32).to_be_bytes())
551        }
552        i64::MIN..=-2147483649 => {
553            // int64
554            writer.write_all(&[0xd3])?;
555            writer.write_all(&n.to_be_bytes())
556        }
557        0..=i64::MAX => {
558            // Use unsigned logic for positive range
559            write_u64(writer, n as u64)
560        }
561    }
562}
563
564fn write_map_len<W: Write>(writer: &mut W, len: usize) -> io::Result<()> {
565    match len {
566        0..=15 => {
567            // fixmap
568            writer.write_all(&[(0x80 | len as u8)])
569        }
570        16..=65535 => {
571            // map16
572            writer.write_all(&[0xde])?;
573            writer.write_all(&(len as u16).to_be_bytes())
574        }
575        _ => {
576            // map32
577            writer.write_all(&[0xdf])?;
578            writer.write_all(&(len as u32).to_be_bytes())
579        }
580    }
581}
582
583#[cfg(test)]
584mod tests {
585    use super::*;
586    use facet::Facet;
587    use serde::Serialize;
588
589    // Helper function to serialize with rmp_serde
590    fn rmp_serialize<T: Serialize>(value: &T) -> Vec<u8> {
591        // Configure rmp_serde to serialize structs as maps
592        let mut buf = Vec::new();
593        let mut ser = rmp_serde::Serializer::new(&mut buf)
594            .with_bytes(rmp_serde::config::BytesMode::ForceIterables)
595            .with_struct_map();
596        value.serialize(&mut ser).unwrap();
597        buf
598    }
599
600    #[derive(Facet, Serialize, PartialEq, Debug)]
601    struct SimpleStruct {
602        a: u32,
603        b: String,
604        c: bool,
605    }
606
607    #[test]
608    fn test_simple_struct() {
609        let value = SimpleStruct {
610            a: 123,
611            b: "hello".to_string(),
612            c: true,
613        };
614
615        let facet_bytes = to_vec(&value);
616        let rmp_bytes = rmp_serialize(&value);
617
618        assert_eq!(facet_bytes, rmp_bytes);
619    }
620
621    #[derive(Facet, Serialize, PartialEq, Debug)]
622    struct NestedStruct {
623        inner: SimpleStruct,
624        d: Option<i8>,
625        e: Vec<u8>,
626    }
627
628    #[test]
629    fn test_nested_struct() {
630        let value = NestedStruct {
631            inner: SimpleStruct {
632                a: 456,
633                b: "world".to_string(),
634                c: false,
635            },
636            d: Some(-5),
637            e: vec![1, 2, 3, 4, 5],
638        };
639
640        let facet_bytes = to_vec(&value);
641        let rmp_bytes = rmp_serialize(&value);
642
643        assert_eq!(facet_bytes, rmp_bytes);
644    }
645
646    #[test]
647    fn test_nested_struct_none() {
648        let value = NestedStruct {
649            inner: SimpleStruct {
650                a: 789,
651                b: "another".to_string(),
652                c: true,
653            },
654            d: None,
655            e: vec![0], // rmp can't serialize empty bin8 correctly
656        };
657
658        let facet_bytes = to_vec(&value);
659        let rmp_bytes = rmp_serialize(&value);
660
661        assert_eq!(facet_bytes, rmp_bytes);
662    }
663
664    #[derive(Facet, Serialize, PartialEq, Debug)]
665    #[repr(u8)]
666    #[allow(dead_code)]
667    enum TestEnum {
668        Unit,
669        Tuple(u32, String),
670        Struct { name: String, value: i64 },
671    }
672
673    #[test]
674    fn test_enum_unit() {
675        let value = TestEnum::Unit;
676        let facet_bytes = to_vec(&value);
677        // rmp-serde serializes unit variants as just the string name
678        let rmp_bytes = rmp_serialize(&"Unit");
679        assert_eq!(facet_bytes, rmp_bytes);
680    }
681
682    #[test]
683    fn test_f32() {
684        #[derive(Facet, Serialize, PartialEq, Debug)]
685        struct FloatStruct {
686            value: f32,
687        }
688
689        let value = FloatStruct { value: 1.23 };
690        let facet_bytes = to_vec(&value);
691        let rmp_bytes = rmp_serialize(&value);
692        assert_eq!(facet_bytes, rmp_bytes);
693    }
694
695    #[test]
696    fn test_f64() {
697        #[derive(Facet, Serialize, PartialEq, Debug)]
698        struct DoubleStruct {
699            value: f64,
700        }
701
702        let value = DoubleStruct { value: -4.56e7 };
703        let facet_bytes = to_vec(&value);
704        let rmp_bytes = rmp_serialize(&value);
705        assert_eq!(facet_bytes, rmp_bytes);
706    }
707
708    #[test]
709    fn test_i8() {
710        #[derive(Facet, Serialize, PartialEq, Debug)]
711        struct I8Struct {
712            value: i8,
713        }
714
715        let value = I8Struct { value: -10 };
716        let facet_bytes = to_vec(&value);
717        let rmp_bytes = rmp_serialize(&value);
718        assert_eq!(facet_bytes, rmp_bytes);
719    }
720
721    #[test]
722    fn test_i16() {
723        #[derive(Facet, Serialize, PartialEq, Debug)]
724        struct I16Struct {
725            value: i16,
726        }
727
728        let value = I16Struct { value: -1000 };
729        let facet_bytes = to_vec(&value);
730        let rmp_bytes = rmp_serialize(&value);
731        assert_eq!(facet_bytes, rmp_bytes);
732    }
733
734    #[test]
735    fn test_i32() {
736        #[derive(Facet, Serialize, PartialEq, Debug)]
737        struct I32Struct {
738            value: i32,
739        }
740
741        let value = I32Struct { value: -100000 };
742        let facet_bytes = to_vec(&value);
743        let rmp_bytes = rmp_serialize(&value);
744        assert_eq!(facet_bytes, rmp_bytes);
745    }
746
747    #[test]
748    fn test_i64() {
749        #[derive(Facet, Serialize, PartialEq, Debug)]
750        struct I64Struct {
751            value: i64,
752        }
753
754        let value = I64Struct {
755            value: -10000000000,
756        };
757        let facet_bytes = to_vec(&value);
758        let rmp_bytes = rmp_serialize(&value);
759        assert_eq!(facet_bytes, rmp_bytes);
760    }
761
762    #[test]
763    fn test_u8() {
764        #[derive(Facet, Serialize, PartialEq, Debug)]
765        struct U8Struct {
766            value: u8,
767        }
768
769        let value = U8Struct { value: 10 };
770        let facet_bytes = to_vec(&value);
771        let rmp_bytes = rmp_serialize(&value);
772        assert_eq!(facet_bytes, rmp_bytes);
773    }
774
775    #[test]
776    fn test_u16() {
777        #[derive(Facet, Serialize, PartialEq, Debug)]
778        struct U16Struct {
779            value: u16,
780        }
781
782        let value = U16Struct { value: 1000 };
783        let facet_bytes = to_vec(&value);
784        let rmp_bytes = rmp_serialize(&value);
785        assert_eq!(facet_bytes, rmp_bytes);
786    }
787
788    #[test]
789    fn test_u32() {
790        #[derive(Facet, Serialize, PartialEq, Debug)]
791        struct U32Struct {
792            value: u32,
793        }
794
795        let value = U32Struct { value: 100000 };
796        let facet_bytes = to_vec(&value);
797        let rmp_bytes = rmp_serialize(&value);
798        assert_eq!(facet_bytes, rmp_bytes);
799    }
800
801    #[test]
802    fn test_u64() {
803        #[derive(Facet, Serialize, PartialEq, Debug)]
804        struct U64Struct {
805            value: u64,
806        }
807
808        let value = U64Struct { value: 10000000000 };
809        let facet_bytes = to_vec(&value);
810        let rmp_bytes = rmp_serialize(&value);
811        assert_eq!(facet_bytes, rmp_bytes);
812    }
813
814    #[test]
815    fn test_bytes() {
816        #[derive(Facet, Serialize, PartialEq, Debug)]
817        struct BytesStruct {
818            value: Vec<u8>,
819        }
820
821        let value = BytesStruct {
822            value: b"binary data".to_vec(),
823        };
824        let facet_bytes = to_vec(&value);
825        let rmp_bytes = rmp_serialize(&value);
826        assert_eq!(facet_bytes, rmp_bytes);
827    }
828
829    #[test]
830    fn test_string() {
831        #[derive(Facet, Serialize, PartialEq, Debug)]
832        struct StringStruct {
833            value: String,
834        }
835
836        let value = StringStruct {
837            value: "string data".to_string(),
838        };
839        let facet_bytes = to_vec(&value);
840        let rmp_bytes = rmp_serialize(&value);
841        assert_eq!(facet_bytes, rmp_bytes);
842    }
843
844    #[test]
845    fn test_char() {
846        #[derive(Facet, Serialize, PartialEq, Debug)]
847        struct CharStruct {
848            value: char,
849        }
850
851        let value = CharStruct { value: '✅' };
852        let facet_bytes = to_vec(&value);
853        let rmp_bytes = rmp_serialize(&value);
854        assert_eq!(facet_bytes, rmp_bytes);
855    }
856
857    #[test]
858    fn test_option_some() {
859        #[derive(Facet, Serialize, PartialEq, Debug)]
860        struct OptionSomeStruct {
861            value: Option<i32>,
862        }
863
864        let value = OptionSomeStruct { value: Some(99) };
865        let facet_bytes = to_vec(&value);
866        let rmp_bytes = rmp_serialize(&value);
867        assert_eq!(facet_bytes, rmp_bytes);
868    }
869
870    #[test]
871    fn test_option_none() {
872        #[derive(Facet, Serialize, PartialEq, Debug)]
873        struct OptionNoneStruct {
874            value: Option<String>,
875        }
876
877        let value = OptionNoneStruct { value: None };
878        let facet_bytes = to_vec(&value);
879        let rmp_bytes = rmp_serialize(&value);
880        assert_eq!(facet_bytes, rmp_bytes);
881    }
882
883    #[test]
884    fn test_unit() {
885        #[derive(Facet, Serialize, PartialEq, Debug)]
886        struct UnitStruct {
887            value: (),
888        }
889
890        let value = UnitStruct { value: () };
891        let facet_bytes = to_vec(&value);
892        let rmp_bytes = rmp_serialize(&value);
893        assert_eq!(facet_bytes, rmp_bytes);
894    }
895
896    #[test]
897    fn test_empty_vec() {
898        #[derive(Facet, Serialize, PartialEq, Debug)]
899        struct EmptyVecStruct {
900            value: Vec<i32>,
901        }
902
903        let value = EmptyVecStruct { value: vec![] };
904        let facet_bytes = to_vec(&value);
905
906        // Empty collections are serialized as nil in facet-msgpack to maintain consistency
907        // with how unit types are handled. This ensures uniform behavior for "empty" values.
908        let expected = vec![0x81, 0xa5, b'v', b'a', b'l', b'u', b'e', 0xc0]; // map with "value" -> nil
909        assert_eq!(facet_bytes, expected);
910    }
911}