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<'shape, W: Write> Serializer<'shape> 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: &'shape 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            write_array_len(self.writer, l)
171        } else {
172            Err(io::Error::other(
173                "MessagePack requires array length upfront",
174            ))
175        }
176    }
177
178    fn end_array(&mut self) -> Result<(), Self::Error> {
179        trace!("Ending array");
180        // No explicit end marker needed for fixed-length arrays in MessagePack
181        Ok(())
182    }
183
184    // Maps in facet-serialize correspond to MessagePack maps
185    fn start_map(&mut self, len: Option<usize>) -> Result<(), Self::Error> {
186        trace!("Starting map, len: {:?}", len);
187        if let Some(l) = len {
188            write_map_len(self.writer, l)
189        } else {
190            Err(io::Error::other("MessagePack requires map length upfront"))
191        }
192    }
193
194    fn end_map(&mut self) -> Result<(), Self::Error> {
195        trace!("Ending map");
196        // No explicit end marker needed for fixed-length maps in MessagePack
197        Ok(())
198    }
199
200    // Field names are serialized as strings (keys) in MessagePack maps
201    fn serialize_field_name(&mut self, name: &'shape str) -> Result<(), Self::Error> {
202        trace!("Serializing field name: {}", name);
203        write_str(self.writer, name)
204    }
205}
206
207fn write_nil<W: Write>(writer: &mut W) -> io::Result<()> {
208    writer.write_all(&[0xc0])
209}
210
211fn write_bool<W: Write>(writer: &mut W, val: bool) -> io::Result<()> {
212    if val {
213        writer.write_all(&[0xc3]) // true
214    } else {
215        writer.write_all(&[0xc2]) // false
216    }
217}
218
219fn write_f32<W: Write>(writer: &mut W, n: f32) -> io::Result<()> {
220    writer.write_all(&[0xca])?; // float 32
221    writer.write_all(&n.to_be_bytes())
222}
223
224fn write_f64<W: Write>(writer: &mut W, n: f64) -> io::Result<()> {
225    writer.write_all(&[0xcb])?; // float 64
226    writer.write_all(&n.to_be_bytes())
227}
228
229fn write_bin<W: Write>(writer: &mut W, bytes: &[u8]) -> io::Result<()> {
230    let len = bytes.len();
231    match len {
232        0..=255 => {
233            // bin 8
234            writer.write_all(&[0xc4, len as u8])?;
235        }
236        256..=65535 => {
237            // bin 16
238            writer.write_all(&[0xc5])?;
239            writer.write_all(&(len as u16).to_be_bytes())?;
240        }
241        _ => {
242            // bin 32
243            writer.write_all(&[0xc6])?;
244            writer.write_all(&(len as u32).to_be_bytes())?;
245        }
246    }
247    writer.write_all(bytes)
248}
249
250fn write_array_len<W: Write>(writer: &mut W, len: usize) -> io::Result<()> {
251    match len {
252        0..=15 => {
253            // fixarray
254            writer.write_all(&[(0x90 | len as u8)])
255        }
256        16..=65535 => {
257            // array 16
258            writer.write_all(&[0xdc])?;
259            writer.write_all(&(len as u16).to_be_bytes())
260        }
261        _ => {
262            // array 32
263            writer.write_all(&[0xdd])?;
264            writer.write_all(&(len as u32).to_be_bytes())
265        }
266    }
267}
268
269// --- Existing write_* functions from the original file ---
270// (write_str, write_u8, write_u16, write_u32, write_u64, write_i8, write_i16, write_i32, write_i64, write_map_len)
271// These remain largely unchanged.
272
273fn write_str<W: Write>(writer: &mut W, s: &str) -> io::Result<()> {
274    let bytes = s.as_bytes();
275    let len = bytes.len();
276
277    match len {
278        0..=31 => {
279            // fixstr
280            writer.write_all(&[(0xa0 | len as u8)])?;
281        }
282        32..=255 => {
283            // str8
284            writer.write_all(&[0xd9, len as u8])?;
285        }
286        256..=65535 => {
287            // str16
288            writer.write_all(&[0xda])?;
289            writer.write_all(&(len as u16).to_be_bytes())?;
290        }
291        _ => {
292            // str32
293            writer.write_all(&[0xdb])?;
294            writer.write_all(&(len as u32).to_be_bytes())?;
295        }
296    }
297    writer.write_all(bytes)
298}
299
300fn write_u8<W: Write>(writer: &mut W, n: u8) -> io::Result<()> {
301    match n {
302        0..=127 => {
303            // positive fixint
304            writer.write_all(&[n])
305        }
306        _ => {
307            // uint8
308            writer.write_all(&[0xcc, n])
309        }
310    }
311}
312
313fn write_u16<W: Write>(writer: &mut W, n: u16) -> io::Result<()> {
314    match n {
315        0..=127 => {
316            // positive fixint
317            writer.write_all(&[n as u8])
318        }
319        128..=255 => {
320            // uint8
321            writer.write_all(&[0xcc, n as u8])
322        }
323        _ => {
324            // uint16
325            writer.write_all(&[0xcd])?;
326            writer.write_all(&n.to_be_bytes())
327        }
328    }
329}
330
331fn write_u32<W: Write>(writer: &mut W, n: u32) -> io::Result<()> {
332    match n {
333        0..=127 => {
334            // positive fixint
335            writer.write_all(&[n as u8])
336        }
337        128..=255 => {
338            // uint8
339            writer.write_all(&[0xcc, n as u8])
340        }
341        256..=65535 => {
342            // uint16
343            writer.write_all(&[0xcd])?;
344            writer.write_all(&(n as u16).to_be_bytes())
345        }
346        _ => {
347            // uint32
348            writer.write_all(&[0xce])?;
349            writer.write_all(&n.to_be_bytes())
350        }
351    }
352}
353
354fn write_u64<W: Write>(writer: &mut W, n: u64) -> io::Result<()> {
355    match n {
356        0..=127 => {
357            // positive fixint
358            writer.write_all(&[n as u8])
359        }
360        128..=255 => {
361            // uint8
362            writer.write_all(&[0xcc, n as u8])
363        }
364        256..=65535 => {
365            // uint16
366            writer.write_all(&[0xcd])?;
367            writer.write_all(&(n as u16).to_be_bytes())
368        }
369        65536..=4294967295 => {
370            // uint32
371            writer.write_all(&[0xce])?;
372            writer.write_all(&(n as u32).to_be_bytes())
373        }
374        _ => {
375            // uint64
376            writer.write_all(&[0xcf])?;
377            writer.write_all(&n.to_be_bytes())
378        }
379    }
380}
381
382fn write_i8<W: Write>(writer: &mut W, n: i8) -> io::Result<()> {
383    match n {
384        -32..=-1 => {
385            // negative fixint
386            writer.write_all(&[n as u8])
387        }
388        -128..=-33 => {
389            // int8
390            writer.write_all(&[0xd0, n as u8])
391        }
392        0..=127 => {
393            // positive fixint or uint8
394            write_u8(writer, n as u8) // Reuse u8 logic for positive values
395        }
396    }
397}
398
399fn write_i16<W: Write>(writer: &mut W, n: i16) -> io::Result<()> {
400    match n {
401        -32..=-1 => {
402            // negative fixint
403            writer.write_all(&[n as u8])
404        }
405        -128..=-33 => {
406            // int8
407            writer.write_all(&[0xd0, n as u8])
408        }
409        -32768..=-129 => {
410            // int16
411            writer.write_all(&[0xd1])?;
412            writer.write_all(&n.to_be_bytes())
413        }
414        0..=32767 => {
415            // Use unsigned logic for positive range
416            write_u16(writer, n as u16)
417        }
418    }
419}
420
421fn write_i32<W: Write>(writer: &mut W, n: i32) -> io::Result<()> {
422    match n {
423        -32..=-1 => {
424            // negative fixint
425            writer.write_all(&[n as u8])
426        }
427        -128..=-33 => {
428            // int8
429            writer.write_all(&[0xd0, n as u8])
430        }
431        -32768..=-129 => {
432            // int16
433            writer.write_all(&[0xd1])?;
434            writer.write_all(&(n as i16).to_be_bytes())
435        }
436        -2147483648..=-32769 => {
437            // int32
438            writer.write_all(&[0xd2])?;
439            writer.write_all(&n.to_be_bytes())
440        }
441        0..=2147483647 => {
442            // Use unsigned logic for positive range
443            write_u32(writer, n as u32)
444        }
445    }
446}
447
448fn write_i64<W: Write>(writer: &mut W, n: i64) -> io::Result<()> {
449    match n {
450        -32..=-1 => {
451            // negative fixint
452            writer.write_all(&[n as u8])
453        }
454        -128..=-33 => {
455            // int8
456            writer.write_all(&[0xd0, n as u8])
457        }
458        -32768..=-129 => {
459            // int16
460            writer.write_all(&[0xd1])?;
461            writer.write_all(&(n as i16).to_be_bytes())
462        }
463        -2147483648..=-32769 => {
464            // int32
465            writer.write_all(&[0xd2])?;
466            writer.write_all(&(n as i32).to_be_bytes())
467        }
468        i64::MIN..=-2147483649 => {
469            // int64
470            writer.write_all(&[0xd3])?;
471            writer.write_all(&n.to_be_bytes())
472        }
473        0..=i64::MAX => {
474            // Use unsigned logic for positive range
475            write_u64(writer, n as u64)
476        }
477    }
478}
479
480fn write_map_len<W: Write>(writer: &mut W, len: usize) -> io::Result<()> {
481    match len {
482        0..=15 => {
483            // fixmap
484            writer.write_all(&[(0x80 | len as u8)])
485        }
486        16..=65535 => {
487            // map16
488            writer.write_all(&[0xde])?;
489            writer.write_all(&(len as u16).to_be_bytes())
490        }
491        _ => {
492            // map32
493            writer.write_all(&[0xdf])?;
494            writer.write_all(&(len as u32).to_be_bytes())
495        }
496    }
497}
498
499#[cfg(test)]
500mod tests {
501    use super::*;
502    use facet::Facet;
503    use serde::Serialize; // Import serde::Serialize
504
505    // Helper function to serialize with rmp_serde
506    fn rmp_serialize<T: Serialize>(value: &T) -> Vec<u8> {
507        // Configure rmp_serde to serialize structs as maps
508        let mut buf = Vec::new();
509        let mut ser = rmp_serde::Serializer::new(&mut buf)
510            .with_bytes(rmp_serde::config::BytesMode::ForceIterables)
511            .with_struct_map();
512        value.serialize(&mut ser).unwrap();
513        buf
514    }
515
516    #[derive(Facet, Serialize, PartialEq, Debug)] // Add Serialize
517    struct SimpleStruct {
518        a: u32,
519        b: String,
520        c: bool,
521    }
522
523    #[test]
524    fn test_simple_struct() {
525        let value = SimpleStruct {
526            a: 123,
527            b: "hello".to_string(),
528            c: true,
529        };
530
531        let facet_bytes = to_vec(&value);
532        let rmp_bytes = rmp_serialize(&value);
533
534        assert_eq!(facet_bytes, rmp_bytes);
535    }
536
537    #[derive(Facet, Serialize, PartialEq, Debug)] // Add Serialize
538    struct NestedStruct {
539        inner: SimpleStruct,
540        d: Option<i8>,
541        e: Vec<u8>,
542    }
543
544    #[test]
545    fn test_nested_struct() {
546        let value = NestedStruct {
547            inner: SimpleStruct {
548                a: 456,
549                b: "world".to_string(),
550                c: false,
551            },
552            d: Some(-5),
553            e: vec![1, 2, 3, 4, 5],
554        };
555
556        let facet_bytes = to_vec(&value);
557        let rmp_bytes = rmp_serialize(&value);
558
559        assert_eq!(facet_bytes, rmp_bytes);
560    }
561
562    #[test]
563    fn test_nested_struct_none() {
564        let value = NestedStruct {
565            inner: SimpleStruct {
566                a: 789,
567                b: "another".to_string(),
568                c: true,
569            },
570            d: None,
571            e: vec![0], // rmp can't serialize empty bin8 correctly
572        };
573
574        let facet_bytes = to_vec(&value);
575        let rmp_bytes = rmp_serialize(&value);
576
577        assert_eq!(facet_bytes, rmp_bytes);
578    }
579
580    #[derive(Facet, Serialize, PartialEq, Debug)] // Add Serialize
581    #[repr(u8)]
582    #[allow(dead_code)]
583    enum TestEnum {
584        Unit,
585        Tuple(u32, String),
586        Struct { name: String, value: i64 },
587    }
588
589    #[test]
590    fn test_enum_unit() {
591        let value = TestEnum::Unit;
592        let facet_bytes = to_vec(&value);
593        // rmp-serde serializes unit variants as just the string name
594        let rmp_bytes = rmp_serialize(&"Unit");
595        assert_eq!(facet_bytes, rmp_bytes);
596    }
597
598    #[test]
599    fn test_various_types() {
600        #[derive(Facet, Serialize, PartialEq, Debug)]
601        struct Various {
602            f1: f32,
603            f2: f64,
604            i1: i8,
605            i2: i16,
606            i3: i32,
607            i4: i64,
608            u1: u8,
609            u2: u16,
610            u3: u32,
611            u4: u64,
612            b: Vec<u8>,
613            s: String,
614            c: char,
615            opt_some: Option<i32>,
616            opt_none: Option<String>,
617            unit: (),
618        }
619
620        let value = Various {
621            f1: 1.23,
622            f2: -4.56e7,
623            i1: -10,
624            i2: -1000,
625            i3: -100000,
626            i4: -10000000000,
627            u1: 10,
628            u2: 1000,
629            u3: 100000,
630            u4: 10000000000,
631            b: b"binary data".to_vec(),
632            s: "string data".to_string(),
633            c: '✅',
634            opt_some: Some(99),
635            opt_none: None,
636            unit: (),
637        };
638
639        let facet_bytes = to_vec(&value);
640        let rmp_bytes = rmp_serialize(&value);
641
642        assert_eq!(facet_bytes, rmp_bytes);
643    }
644}