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::new(
53            io::ErrorKind::Other,
54            "u128 is not directly supported by MessagePack",
55        ))
56    }
57
58    // Map usize to u64 as MessagePack doesn't have a specific usize type
59    fn serialize_usize(&mut self, value: usize) -> Result<(), Self::Error> {
60        trace!("Serializing usize: {}", value);
61        write_u64(self.writer, value as u64) // Assuming usize fits in u64
62    }
63
64    fn serialize_i8(&mut self, value: i8) -> Result<(), Self::Error> {
65        trace!("Serializing i8: {}", value);
66        write_i8(self.writer, value)
67    }
68
69    fn serialize_i16(&mut self, value: i16) -> Result<(), Self::Error> {
70        trace!("Serializing i16: {}", value);
71        write_i16(self.writer, value)
72    }
73
74    fn serialize_i32(&mut self, value: i32) -> Result<(), Self::Error> {
75        trace!("Serializing i32: {}", value);
76        write_i32(self.writer, value)
77    }
78
79    fn serialize_i64(&mut self, value: i64) -> Result<(), Self::Error> {
80        trace!("Serializing i64: {}", value);
81        write_i64(self.writer, value)
82    }
83
84    // TODO: Implement serialize_i128 if needed for MessagePack, otherwise return error or panic
85    fn serialize_i128(&mut self, _value: i128) -> Result<(), Self::Error> {
86        Err(io::Error::new(
87            io::ErrorKind::Other,
88            "i128 is not directly supported by MessagePack",
89        ))
90    }
91
92    // Map isize to i64 as MessagePack doesn't have a specific isize type
93    fn serialize_isize(&mut self, value: isize) -> Result<(), Self::Error> {
94        trace!("Serializing isize: {}", value);
95        write_i64(self.writer, value as i64) // Assuming isize fits in i64
96    }
97
98    fn serialize_f32(&mut self, value: f32) -> Result<(), Self::Error> {
99        trace!("Serializing f32: {}", value);
100        write_f32(self.writer, value)
101    }
102
103    fn serialize_f64(&mut self, value: f64) -> Result<(), Self::Error> {
104        trace!("Serializing f64: {}", value);
105        write_f64(self.writer, value)
106    }
107
108    fn serialize_bool(&mut self, value: bool) -> Result<(), Self::Error> {
109        trace!("Serializing bool: {}", value);
110        write_bool(self.writer, value)
111    }
112
113    // Characters are often serialized as strings in MessagePack
114    fn serialize_char(&mut self, value: char) -> Result<(), Self::Error> {
115        trace!("Serializing char: {}", value);
116        let mut buf = [0; 4];
117        write_str(self.writer, value.encode_utf8(&mut buf))
118    }
119
120    fn serialize_str(&mut self, value: &str) -> Result<(), Self::Error> {
121        trace!("Serializing str: {}", value);
122        write_str(self.writer, value)
123    }
124
125    fn serialize_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error> {
126        trace!("Serializing bytes, len: {}", value.len());
127        write_bin(self.writer, value)
128    }
129
130    fn serialize_none(&mut self) -> Result<(), Self::Error> {
131        trace!("Serializing none");
132        write_nil(self.writer)
133    }
134
135    fn serialize_unit(&mut self) -> Result<(), Self::Error> {
136        trace!("Serializing unit");
137        write_nil(self.writer) // Represent unit as nil
138    }
139
140    // Unit variants can be represented as strings or specific codes if needed.
141    // Using string representation for now.
142    fn serialize_unit_variant(
143        &mut self,
144        _variant_index: usize,
145        variant_name: &'static str,
146    ) -> Result<(), Self::Error> {
147        trace!("Serializing unit variant: {}", variant_name);
148        write_str(self.writer, variant_name)
149    }
150
151    fn start_object(&mut self, len: Option<usize>) -> Result<(), Self::Error> {
152        trace!("Starting object, len: {:?}", len);
153        if let Some(l) = len {
154            write_map_len(self.writer, l)
155        } else {
156            // MessagePack doesn't have an indefinite length map marker.
157            // This might require buffering or a different approach if the length is unknown.
158            // For now, assume length is always known by `facet-serialize`.
159            Err(io::Error::new(
160                io::ErrorKind::Other,
161                "MessagePack requires map length upfront",
162            ))
163        }
164    }
165
166    fn end_object(&mut self) -> Result<(), Self::Error> {
167        trace!("Ending object");
168        // No explicit end marker needed for fixed-length maps in MessagePack
169        Ok(())
170    }
171
172    fn start_array(&mut self, len: Option<usize>) -> Result<(), Self::Error> {
173        trace!("Starting array, len: {:?}", len);
174        if let Some(l) = len {
175            write_array_len(self.writer, l)
176        } else {
177            Err(io::Error::new(
178                io::ErrorKind::Other,
179                "MessagePack requires array length upfront",
180            ))
181        }
182    }
183
184    fn end_array(&mut self) -> Result<(), Self::Error> {
185        trace!("Ending array");
186        // No explicit end marker needed for fixed-length arrays in MessagePack
187        Ok(())
188    }
189
190    // Maps in facet-serialize correspond to MessagePack maps
191    fn start_map(&mut self, len: Option<usize>) -> Result<(), Self::Error> {
192        trace!("Starting map, len: {:?}", len);
193        if let Some(l) = len {
194            write_map_len(self.writer, l)
195        } else {
196            Err(io::Error::new(
197                io::ErrorKind::Other,
198                "MessagePack requires map length upfront",
199            ))
200        }
201    }
202
203    fn end_map(&mut self) -> Result<(), Self::Error> {
204        trace!("Ending map");
205        // No explicit end marker needed for fixed-length maps in MessagePack
206        Ok(())
207    }
208
209    // Field names are serialized as strings (keys) in MessagePack maps
210    fn serialize_field_name(&mut self, name: &'static str) -> Result<(), Self::Error> {
211        trace!("Serializing field name: {}", name);
212        write_str(self.writer, name)
213    }
214}
215
216fn write_nil<W: Write>(writer: &mut W) -> io::Result<()> {
217    writer.write_all(&[0xc0])
218}
219
220fn write_bool<W: Write>(writer: &mut W, val: bool) -> io::Result<()> {
221    if val {
222        writer.write_all(&[0xc3]) // true
223    } else {
224        writer.write_all(&[0xc2]) // false
225    }
226}
227
228fn write_f32<W: Write>(writer: &mut W, n: f32) -> io::Result<()> {
229    writer.write_all(&[0xca])?; // float 32
230    writer.write_all(&n.to_be_bytes())
231}
232
233fn write_f64<W: Write>(writer: &mut W, n: f64) -> io::Result<()> {
234    writer.write_all(&[0xcb])?; // float 64
235    writer.write_all(&n.to_be_bytes())
236}
237
238fn write_bin<W: Write>(writer: &mut W, bytes: &[u8]) -> io::Result<()> {
239    let len = bytes.len();
240    match len {
241        0..=255 => {
242            // bin 8
243            writer.write_all(&[0xc4, len as u8])?;
244        }
245        256..=65535 => {
246            // bin 16
247            writer.write_all(&[0xc5])?;
248            writer.write_all(&(len as u16).to_be_bytes())?;
249        }
250        _ => {
251            // bin 32
252            writer.write_all(&[0xc6])?;
253            writer.write_all(&(len as u32).to_be_bytes())?;
254        }
255    }
256    writer.write_all(bytes)
257}
258
259fn write_array_len<W: Write>(writer: &mut W, len: usize) -> io::Result<()> {
260    match len {
261        0..=15 => {
262            // fixarray
263            writer.write_all(&[(0x90 | len as u8)])
264        }
265        16..=65535 => {
266            // array 16
267            writer.write_all(&[0xdc])?;
268            writer.write_all(&(len as u16).to_be_bytes())
269        }
270        _ => {
271            // array 32
272            writer.write_all(&[0xdd])?;
273            writer.write_all(&(len as u32).to_be_bytes())
274        }
275    }
276}
277
278// --- Existing write_* functions from the original file ---
279// (write_str, write_u8, write_u16, write_u32, write_u64, write_i8, write_i16, write_i32, write_i64, write_map_len)
280// These remain largely unchanged.
281
282fn write_str<W: Write>(writer: &mut W, s: &str) -> io::Result<()> {
283    let bytes = s.as_bytes();
284    let len = bytes.len();
285
286    match len {
287        0..=31 => {
288            // fixstr
289            writer.write_all(&[(0xa0 | len as u8)])?;
290        }
291        32..=255 => {
292            // str8
293            writer.write_all(&[0xd9, len as u8])?;
294        }
295        256..=65535 => {
296            // str16
297            writer.write_all(&[0xda])?;
298            writer.write_all(&(len as u16).to_be_bytes())?;
299        }
300        _ => {
301            // str32
302            writer.write_all(&[0xdb])?;
303            writer.write_all(&(len as u32).to_be_bytes())?;
304        }
305    }
306    writer.write_all(bytes)
307}
308
309fn write_u8<W: Write>(writer: &mut W, n: u8) -> io::Result<()> {
310    match n {
311        0..=127 => {
312            // positive fixint
313            writer.write_all(&[n])
314        }
315        _ => {
316            // uint8
317            writer.write_all(&[0xcc, n])
318        }
319    }
320}
321
322fn write_u16<W: Write>(writer: &mut W, n: u16) -> io::Result<()> {
323    match n {
324        0..=127 => {
325            // positive fixint
326            writer.write_all(&[n as u8])
327        }
328        128..=255 => {
329            // uint8
330            writer.write_all(&[0xcc, n as u8])
331        }
332        _ => {
333            // uint16
334            writer.write_all(&[0xcd])?;
335            writer.write_all(&n.to_be_bytes())
336        }
337    }
338}
339
340fn write_u32<W: Write>(writer: &mut W, n: u32) -> io::Result<()> {
341    match n {
342        0..=127 => {
343            // positive fixint
344            writer.write_all(&[n as u8])
345        }
346        128..=255 => {
347            // uint8
348            writer.write_all(&[0xcc, n as u8])
349        }
350        256..=65535 => {
351            // uint16
352            writer.write_all(&[0xcd])?;
353            writer.write_all(&(n as u16).to_be_bytes())
354        }
355        _ => {
356            // uint32
357            writer.write_all(&[0xce])?;
358            writer.write_all(&n.to_be_bytes())
359        }
360    }
361}
362
363fn write_u64<W: Write>(writer: &mut W, n: u64) -> io::Result<()> {
364    match n {
365        0..=127 => {
366            // positive fixint
367            writer.write_all(&[n as u8])
368        }
369        128..=255 => {
370            // uint8
371            writer.write_all(&[0xcc, n as u8])
372        }
373        256..=65535 => {
374            // uint16
375            writer.write_all(&[0xcd])?;
376            writer.write_all(&(n as u16).to_be_bytes())
377        }
378        65536..=4294967295 => {
379            // uint32
380            writer.write_all(&[0xce])?;
381            writer.write_all(&(n as u32).to_be_bytes())
382        }
383        _ => {
384            // uint64
385            writer.write_all(&[0xcf])?;
386            writer.write_all(&n.to_be_bytes())
387        }
388    }
389}
390
391fn write_i8<W: Write>(writer: &mut W, n: i8) -> io::Result<()> {
392    match n {
393        -32..=-1 => {
394            // negative fixint
395            writer.write_all(&[n as u8])
396        }
397        -128..=-33 => {
398            // int8
399            writer.write_all(&[0xd0, n as u8])
400        }
401        0..=127 => {
402            // positive fixint or uint8
403            write_u8(writer, n as u8) // Reuse u8 logic for positive values
404        }
405    }
406}
407
408fn write_i16<W: Write>(writer: &mut W, n: i16) -> io::Result<()> {
409    match n {
410        -32..=-1 => {
411            // negative fixint
412            writer.write_all(&[n as u8])
413        }
414        -128..=-33 => {
415            // int8
416            writer.write_all(&[0xd0, n as u8])
417        }
418        -32768..=-129 => {
419            // int16
420            writer.write_all(&[0xd1])?;
421            writer.write_all(&n.to_be_bytes())
422        }
423        0..=32767 => {
424            // Use unsigned logic for positive range
425            write_u16(writer, n as u16)
426        }
427    }
428}
429
430fn write_i32<W: Write>(writer: &mut W, n: i32) -> io::Result<()> {
431    match n {
432        -32..=-1 => {
433            // negative fixint
434            writer.write_all(&[n as u8])
435        }
436        -128..=-33 => {
437            // int8
438            writer.write_all(&[0xd0, n as u8])
439        }
440        -32768..=-129 => {
441            // int16
442            writer.write_all(&[0xd1])?;
443            writer.write_all(&(n as i16).to_be_bytes())
444        }
445        -2147483648..=-32769 => {
446            // int32
447            writer.write_all(&[0xd2])?;
448            writer.write_all(&n.to_be_bytes())
449        }
450        0..=2147483647 => {
451            // Use unsigned logic for positive range
452            write_u32(writer, n as u32)
453        }
454    }
455}
456
457fn write_i64<W: Write>(writer: &mut W, n: i64) -> io::Result<()> {
458    match n {
459        -32..=-1 => {
460            // negative fixint
461            writer.write_all(&[n as u8])
462        }
463        -128..=-33 => {
464            // int8
465            writer.write_all(&[0xd0, n as u8])
466        }
467        -32768..=-129 => {
468            // int16
469            writer.write_all(&[0xd1])?;
470            writer.write_all(&(n as i16).to_be_bytes())
471        }
472        -2147483648..=-32769 => {
473            // int32
474            writer.write_all(&[0xd2])?;
475            writer.write_all(&(n as i32).to_be_bytes())
476        }
477        i64::MIN..=-2147483649 => {
478            // int64
479            writer.write_all(&[0xd3])?;
480            writer.write_all(&n.to_be_bytes())
481        }
482        0..=i64::MAX => {
483            // Use unsigned logic for positive range
484            write_u64(writer, n as u64)
485        }
486    }
487}
488
489fn write_map_len<W: Write>(writer: &mut W, len: usize) -> io::Result<()> {
490    match len {
491        0..=15 => {
492            // fixmap
493            writer.write_all(&[(0x80 | len as u8)])
494        }
495        16..=65535 => {
496            // map16
497            writer.write_all(&[0xde])?;
498            writer.write_all(&(len as u16).to_be_bytes())
499        }
500        _ => {
501            // map32
502            writer.write_all(&[0xdf])?;
503            writer.write_all(&(len as u32).to_be_bytes())
504        }
505    }
506}
507
508#[cfg(test)]
509mod tests {
510    use super::*;
511    use facet::Facet;
512    use serde::Serialize; // Import serde::Serialize
513
514    // Helper function to serialize with rmp_serde
515    fn rmp_serialize<T: Serialize>(value: &T) -> Vec<u8> {
516        // Configure rmp_serde to serialize structs as maps
517        let mut buf = Vec::new();
518        let mut ser = rmp_serde::Serializer::new(&mut buf).with_struct_map();
519        value.serialize(&mut ser).unwrap();
520        buf
521    }
522
523    #[derive(Facet, Serialize, PartialEq, Debug)] // Add Serialize
524    struct SimpleStruct {
525        a: u32,
526        b: String,
527        c: bool,
528    }
529
530    #[test]
531    fn test_simple_struct() {
532        let value = SimpleStruct {
533            a: 123,
534            b: "hello".to_string(),
535            c: true,
536        };
537
538        let facet_bytes = to_vec(&value);
539        let rmp_bytes = rmp_serialize(&value);
540
541        assert_eq!(facet_bytes, rmp_bytes);
542    }
543
544    #[derive(Facet, Serialize, PartialEq, Debug)] // Add Serialize
545    struct NestedStruct {
546        inner: SimpleStruct,
547        d: Option<i8>,
548        e: Vec<u8>,
549    }
550
551    #[test]
552    fn test_nested_struct() {
553        let value = NestedStruct {
554            inner: SimpleStruct {
555                a: 456,
556                b: "world".to_string(),
557                c: false,
558            },
559            d: Some(-5),
560            e: vec![1, 2, 3, 4, 5],
561        };
562
563        let facet_bytes = to_vec(&value);
564        let rmp_bytes = rmp_serialize(&value);
565
566        assert_eq!(facet_bytes, rmp_bytes);
567    }
568
569    #[test]
570    fn test_nested_struct_none() {
571        let value = NestedStruct {
572            inner: SimpleStruct {
573                a: 789,
574                b: "another".to_string(),
575                c: true,
576            },
577            d: None,
578            e: vec![],
579        };
580
581        let facet_bytes = to_vec(&value);
582        let rmp_bytes = rmp_serialize(&value);
583
584        assert_eq!(facet_bytes, rmp_bytes);
585    }
586
587    #[derive(Facet, Serialize, PartialEq, Debug)] // Add Serialize
588    #[repr(u8)]
589    #[allow(dead_code)]
590    enum TestEnum {
591        Unit,
592        Tuple(u32, String),
593        Struct { name: String, value: i64 },
594    }
595
596    #[test]
597    fn test_enum_unit() {
598        let value = TestEnum::Unit;
599        let facet_bytes = to_vec(&value);
600        // rmp-serde serializes unit variants as just the string name
601        let rmp_bytes = rmp_serialize(&"Unit");
602        assert_eq!(facet_bytes, rmp_bytes);
603    }
604
605    #[test]
606    fn test_various_types() {
607        #[derive(Facet, Serialize, PartialEq, Debug)]
608        struct Various {
609            f1: f32,
610            f2: f64,
611            i1: i8,
612            i2: i16,
613            i3: i32,
614            i4: i64,
615            u1: u8,
616            u2: u16,
617            u3: u32,
618            u4: u64,
619            b: Vec<u8>,
620            s: String,
621            c: char,
622            opt_some: Option<i32>,
623            opt_none: Option<String>,
624            unit: (),
625        }
626
627        let value = Various {
628            f1: 1.23,
629            f2: -4.56e7,
630            i1: -10,
631            i2: -1000,
632            i3: -100000,
633            i4: -10000000000,
634            u1: 10,
635            u2: 1000,
636            u3: 100000,
637            u4: 10000000000,
638            b: b"binary data".to_vec(),
639            s: "string data".to_string(),
640            c: '✅',
641            opt_some: Some(99),
642            opt_none: None,
643            unit: (),
644        };
645
646        let facet_bytes = to_vec(&value);
647        let rmp_bytes = rmp_serialize(&value);
648
649        assert_eq!(facet_bytes, rmp_bytes);
650    }
651}