scale_serialization/
serializer.rs

1use crate::prelude::*;
2use bytes::BufMut;
3use core::fmt;
4use scale_info::{PortableRegistry, TypeInfo};
5use serde::{ser, Serialize};
6
7use crate::{EnumVariant, SpecificType, TupleOrArray};
8
9type TypeId = u32;
10type Result<T> = core::result::Result<T, Error>;
11
12#[derive(TypeInfo)]
13struct Noop;
14
15#[inline]
16pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
17where
18    T: Serialize + ?Sized,
19{
20    let mut out = vec![];
21    to_bytes(&mut out, value)?;
22    Ok(out)
23}
24
25#[inline]
26pub fn to_vec_with_info<T>(
27    value: &T,
28    registry_type: Option<(&PortableRegistry, TypeId)>,
29) -> Result<Vec<u8>>
30where
31    T: Serialize + ?Sized,
32{
33    let mut out = vec![];
34    to_bytes_with_info(&mut out, value, registry_type)?;
35    Ok(out)
36}
37
38pub fn to_bytes<B, T>(bytes: B, value: &T) -> Result<()>
39where
40    T: Serialize + ?Sized,
41    B: BufMut,
42{
43    to_bytes_with_info(bytes, value, None)
44}
45
46pub fn to_bytes_with_info<B, T>(
47    bytes: B,
48    value: &T,
49    registry_type: Option<(&PortableRegistry, TypeId)>,
50) -> Result<()>
51where
52    T: Serialize + ?Sized,
53    B: BufMut,
54{
55    let mut serializer = Serializer::new(bytes, registry_type);
56    value.serialize(&mut serializer)?;
57    Ok(())
58}
59
60/// A serializer that encodes types to SCALE with the option to coerce
61/// the output to an equivalent representation given by some type information.
62pub struct Serializer<'reg, B> {
63    out: B,
64    ty: Option<SpecificType>,
65    registry: Option<&'reg PortableRegistry>,
66}
67
68impl<'reg, B> Serializer<'reg, B>
69where
70    B: BufMut,
71{
72    pub fn new(out: B, registry_type: Option<(&'reg PortableRegistry, TypeId)>) -> Self {
73        let (registry, ty) = match registry_type
74            .map(|(reg, ty_id)| (reg, (reg.resolve(ty_id).unwrap(), reg).into()))
75        {
76            Some((reg, ty)) => (Some(reg), Some(ty)),
77            None => (None, None),
78        };
79        Serializer { out, ty, registry }
80    }
81}
82
83impl<'a, 'reg, B> ser::Serializer for &'a mut Serializer<'reg, B>
84where
85    B: BufMut,
86{
87    type Ok = ();
88    type Error = Error;
89
90    type SerializeSeq = TypedSerializer<'a, 'reg, B>;
91    type SerializeTuple = TypedSerializer<'a, 'reg, B>;
92    type SerializeTupleStruct = TypedSerializer<'a, 'reg, B>;
93    type SerializeTupleVariant = TypedSerializer<'a, 'reg, B>;
94    type SerializeMap = TypedSerializer<'a, 'reg, B>;
95    type SerializeStruct = TypedSerializer<'a, 'reg, B>;
96    type SerializeStructVariant = TypedSerializer<'a, 'reg, B>;
97
98    fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
99        self.maybe_some()?;
100        self.out.put_u8(v.into());
101        Ok(())
102    }
103
104    fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
105        self.maybe_some()?;
106        self.out.put_i8(v);
107        Ok(())
108    }
109
110    fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
111        self.maybe_some()?;
112        self.out.put_i16_le(v);
113        Ok(())
114    }
115
116    fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
117        self.maybe_some()?;
118        self.out.put_i32_le(v);
119        Ok(())
120    }
121
122    fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
123        match self.ty {
124            Some(SpecificType::I8) => self.serialize_i8(v as i8)?,
125            Some(SpecificType::I16) => self.serialize_i16(v as i16)?,
126            Some(SpecificType::I32) => self.serialize_i32(v as i32)?,
127            _ => {
128                self.maybe_some()?;
129                self.out.put_i64_le(v)
130            }
131        }
132        Ok(())
133    }
134
135    fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
136        self.maybe_some()?;
137        self.out.put_u8(v);
138        Ok(())
139    }
140
141    fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
142        self.maybe_some()?;
143        self.out.put_u16_le(v);
144        Ok(())
145    }
146
147    fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
148        self.maybe_some()?;
149        self.out.put_u32_le(v);
150        Ok(())
151    }
152
153    fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
154        // all numbers in serde_json are the same
155        match self.ty {
156            Some(SpecificType::I8) => self.serialize_i8(v as i8)?,
157            Some(SpecificType::I16) => self.serialize_i16(v as i16)?,
158            Some(SpecificType::I32) => self.serialize_i32(v as i32)?,
159            Some(SpecificType::U8) => self.serialize_u8(v as u8)?,
160            Some(SpecificType::U16) => self.serialize_u16(v as u16)?,
161            Some(SpecificType::U32) => self.serialize_u32(v as u32)?,
162            _ => {
163                self.maybe_some()?;
164                self.out.put_u64_le(v);
165            }
166        }
167        Ok(())
168    }
169
170    fn serialize_f32(self, _v: f32) -> Result<Self::Ok> {
171        unimplemented!()
172    }
173
174    fn serialize_f64(self, _v: f64) -> Result<Self::Ok> {
175        unimplemented!()
176    }
177
178    fn serialize_char(self, _v: char) -> Result<Self::Ok> {
179        unimplemented!()
180    }
181
182    fn serialize_str(self, v: &str) -> Result<Self::Ok> {
183        self.maybe_some()?;
184        if let Some(ref mut var @ SpecificType::Variant(_, _, None)) = &mut self.ty {
185            var.pick_mut(to_vec(v)?, |k| to_vec(k.name()).unwrap());
186            self.out.put_u8(var.variant_id());
187            return Ok(());
188        }
189        compact_number(v.len(), &mut self.out);
190        self.out.put(v.as_bytes());
191        Ok(())
192    }
193
194    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
195        self.maybe_some()?;
196        self.out.put(v);
197        Ok(())
198    }
199
200    fn serialize_none(self) -> Result<Self::Ok> {
201        self.out.put_u8(0x00);
202        Ok(())
203    }
204
205    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok>
206    where
207        T: Serialize,
208    {
209        self.out.put_u8(0x01);
210        value.serialize(self)
211    }
212
213    fn serialize_unit(self) -> Result<Self::Ok> {
214        self.maybe_some()?;
215        Ok(())
216    }
217
218    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
219        self.maybe_some()?;
220        Ok(())
221    }
222
223    fn serialize_unit_variant(
224        self,
225        __name: &'static str,
226        variant_index: u32,
227        _variant: &'static str,
228    ) -> Result<Self::Ok> {
229        self.maybe_some()?;
230        (variant_index as u8).serialize(self)
231    }
232
233    fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> Result<Self::Ok>
234    where
235        T: Serialize,
236    {
237        self.maybe_some()?;
238        value.serialize(self)
239    }
240
241    fn serialize_newtype_variant<T: ?Sized>(
242        self,
243        __name: &'static str,
244        variant_index: u32,
245        _variant: &'static str,
246        value: &T,
247    ) -> Result<Self::Ok>
248    where
249        T: Serialize,
250    {
251        self.maybe_some()?;
252        self.out.put_u8(variant_index as u8);
253        value.serialize(self)
254    }
255
256    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
257        self.maybe_some()?;
258        if matches!(self.ty, None | Some(SpecificType::Sequence(_))) {
259            compact_number(len.expect("known length"), &mut self.out);
260        }
261        Ok(self.into())
262    }
263
264    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
265        self.maybe_some()?;
266        Ok(self.into())
267    }
268
269    fn serialize_tuple_struct(
270        self,
271        __name: &'static str,
272        __len: usize,
273    ) -> Result<Self::SerializeTupleStruct> {
274        self.maybe_some()?;
275        Ok(self.into())
276    }
277
278    fn serialize_tuple_variant(
279        self,
280        __name: &'static str,
281        variant_index: u32,
282        _variant: &'static str,
283        __len: usize,
284    ) -> Result<Self::SerializeTupleVariant> {
285        self.maybe_some()?;
286        self.out.put_u8(variant_index as u8);
287        Ok(self.into())
288    }
289
290    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
291        self.maybe_some()?;
292        if matches!(self.ty, None | Some(SpecificType::Map(_, _))) {
293            compact_number(len.expect("known length"), &mut self.out);
294        }
295        Ok(self.into())
296    }
297
298    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
299        self.maybe_some()?;
300        Ok(self.into())
301    }
302
303    fn serialize_struct_variant(
304        self,
305        __name: &'static str,
306        variant_index: u32,
307        _variant: &'static str,
308        __len: usize,
309    ) -> Result<Self::SerializeStructVariant> {
310        self.maybe_some()?;
311        self.out.put_u8(variant_index as u8);
312        Ok(self.into())
313    }
314}
315
316impl<'a, 'reg, B> Serializer<'reg, B>
317where
318    B: BufMut,
319{
320    // A check to run for every serialize fn since any type could be an Option::Some
321    // if the type info says its an Option assume its Some and extract the inner type
322    fn maybe_some(&mut self) -> Result<()> {
323        match &self.ty {
324            Some(SpecificType::Variant(ref name, v, _)) if name == "Option" => {
325                self.ty = v[1].fields().first().map(|f| self.resolve(f.ty().id()));
326                self.out.put_u8(0x01);
327            }
328            _ => (),
329        }
330        Ok(())
331    }
332
333    fn resolve(&self, ty_id: TypeId) -> SpecificType {
334        let reg = self.registry.expect("called heving type");
335        let ty = reg.resolve(ty_id).expect("in registry");
336        (ty, reg).into()
337    }
338}
339
340///
341pub enum TypedSerializer<'a, 'reg, B> {
342    Empty(&'a mut Serializer<'reg, B>),
343    Composite(&'a mut Serializer<'reg, B>, Vec<TypeId>),
344    Sequence(&'a mut Serializer<'reg, B>, TypeId),
345    Enum(&'a mut Serializer<'reg, B>),
346}
347
348impl<'a, 'reg, B: 'a> From<&'a mut Serializer<'reg, B>> for TypedSerializer<'a, 'reg, B> {
349    fn from(ser: &'a mut Serializer<'reg, B>) -> Self {
350        use SpecificType::*;
351        match ser.ty.take() {
352            Some(Struct(fields)) => {
353                Self::Composite(ser, fields.iter().map(|(_, ty)| *ty).collect())
354            }
355            Some(StructTuple(fields)) => Self::Composite(ser, fields),
356            Some(Tuple(TupleOrArray::Array(ty, _))) => Self::Sequence(ser, ty),
357            Some(Tuple(TupleOrArray::Tuple(fields))) => Self::Composite(ser, fields),
358            Some(Sequence(ty)) => Self::Sequence(ser, ty),
359            Some(Map(_, _)) => Self::Empty(ser),
360            Some(var @ Variant(_, _, Some(_))) => match (&var).into() {
361                EnumVariant::Tuple(_, _, types) => Self::Composite(ser, types),
362                EnumVariant::Struct(_, _, types) => {
363                    Self::Composite(ser, types.iter().map(|(_, ty)| ty.clone()).collect())
364                }
365                _ => Self::Empty(ser),
366            },
367            Some(var @ Variant(_, _, None)) => {
368                ser.ty = Some(var);
369                Self::Enum(ser)
370            }
371            _ => Self::Empty(ser),
372        }
373    }
374}
375
376impl<'a, 'reg, B> TypedSerializer<'a, 'reg, B> {
377    fn serializer(&mut self) -> &mut Serializer<'reg, B> {
378        match self {
379            Self::Empty(ser)
380            | Self::Composite(ser, _)
381            | Self::Enum(ser)
382            | Self::Sequence(ser, _) => ser,
383        }
384    }
385}
386
387impl<'a, 'reg, B> ser::SerializeMap for TypedSerializer<'a, 'reg, B>
388where
389    B: BufMut,
390{
391    type Ok = ();
392    type Error = Error;
393
394    fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()>
395    where
396        T: Serialize,
397    {
398        match self {
399            TypedSerializer::Enum(ser) => {
400                if let Some(ref mut var @ SpecificType::Variant(_, _, None)) = ser.ty {
401                    let key_data = to_vec(key)?;
402                    // assume the key is the name of the variant
403                    var.pick_mut(key_data, |v| to_vec(v.name()).unwrap())
404                        .variant_id()
405                        .serialize(&mut **ser)?;
406                }
407                Ok(())
408            }
409            TypedSerializer::Empty(ser) => key.serialize(&mut **ser),
410            _ => Ok(()),
411        }
412    }
413
414    fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()>
415    where
416        T: Serialize,
417    {
418        match self {
419            TypedSerializer::Composite(ser, types) => {
420                let mut ty = ser.resolve(types.remove(0));
421                // serde_json unwraps newtypes
422                if let SpecificType::StructNewType(ty_id) = ty {
423                    ty = ser.resolve(ty_id)
424                }
425                ser.ty = Some(ty);
426            }
427            TypedSerializer::Enum(ser) => {
428                if let Some(var @ SpecificType::Variant(_, _, Some(_))) = &ser.ty {
429                    if let EnumVariant::NewType(_, _, ty_id) = var.into() {
430                        ser.ty = Some(ser.resolve(ty_id));
431                    }
432                }
433            }
434            _ => {}
435        }
436        value.serialize(self.serializer())
437    }
438
439    fn end(self) -> Result<Self::Ok> {
440        Ok(())
441    }
442}
443
444impl<'a, 'reg, B> ser::SerializeSeq for TypedSerializer<'a, 'reg, B>
445where
446    B: BufMut,
447{
448    type Ok = ();
449    type Error = Error;
450
451    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
452    where
453        T: Serialize,
454    {
455        match self {
456            TypedSerializer::Composite(ser, types) => {
457                let mut ty = ser.resolve(types.remove(0));
458                if let SpecificType::StructNewType(ty_id) = ty {
459                    ty = ser.resolve(ty_id);
460                }
461                ser.ty = Some(ty);
462            }
463            TypedSerializer::Sequence(ser, ty_id) => {
464                let ty = ser.resolve(*ty_id);
465                ser.ty = Some(match ty {
466                    SpecificType::StructNewType(ty_id) => ser.resolve(ty_id),
467                    _ => ty,
468                });
469            }
470            _ => {}
471        };
472        value.serialize(self.serializer())
473    }
474
475    fn end(self) -> Result<Self::Ok> {
476        Ok(())
477    }
478}
479
480impl<'a, 'reg, B> ser::SerializeStruct for TypedSerializer<'a, 'reg, B>
481where
482    B: BufMut,
483{
484    type Ok = ();
485    type Error = Error;
486
487    fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, value: &T) -> Result<()>
488    where
489        T: Serialize,
490    {
491        value.serialize(self.serializer())
492    }
493
494    fn end(self) -> Result<Self::Ok> {
495        Ok(())
496    }
497}
498
499impl<'a, 'reg, B> ser::SerializeStructVariant for TypedSerializer<'a, 'reg, B>
500where
501    B: BufMut,
502{
503    type Ok = ();
504    type Error = Error;
505
506    fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, value: &T) -> Result<()>
507    where
508        T: Serialize,
509    {
510        value.serialize(self.serializer())
511    }
512
513    fn end(self) -> Result<Self::Ok> {
514        Ok(())
515    }
516}
517
518impl<'a, 'reg, B> ser::SerializeTuple for TypedSerializer<'a, 'reg, B>
519where
520    B: BufMut,
521{
522    type Ok = ();
523    type Error = Error;
524
525    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
526    where
527        T: Serialize,
528    {
529        value.serialize(self.serializer())
530    }
531
532    fn end(self) -> Result<Self::Ok> {
533        Ok(())
534    }
535}
536
537impl<'a, 'reg, B> ser::SerializeTupleStruct for TypedSerializer<'a, 'reg, B>
538where
539    B: BufMut,
540{
541    type Ok = ();
542    type Error = Error;
543
544    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
545    where
546        T: Serialize,
547    {
548        value.serialize(self.serializer())
549    }
550
551    fn end(self) -> Result<Self::Ok> {
552        Ok(())
553    }
554}
555
556impl<'a, 'reg, B> ser::SerializeTupleVariant for TypedSerializer<'a, 'reg, B>
557where
558    B: BufMut,
559{
560    type Ok = ();
561    type Error = Error;
562
563    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
564    where
565        T: Serialize,
566    {
567        value.serialize(self.serializer())
568    }
569
570    fn end(self) -> Result<Self::Ok> {
571        Ok(())
572    }
573}
574
575#[derive(Debug)]
576pub enum Error {
577    Ser(String),
578}
579
580impl fmt::Display for Error {
581    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
582        match self {
583            Error::Ser(msg) => write!(f, "{}", msg),
584        }
585    }
586}
587
588impl ser::StdError for Error {}
589
590impl ser::Error for Error {
591    fn custom<T>(msg: T) -> Self
592    where
593        T: fmt::Display,
594    {
595        Error::Ser(msg.to_string())
596    }
597}
598
599// from https://github.com/paritytech/parity-scale-codec/blob/master/src/compact.rs#L336
600#[allow(clippy::all)]
601fn compact_number(n: usize, mut dest: impl BufMut) {
602    match n {
603        0..=0b0011_1111 => dest.put_u8((n as u8) << 2),
604        0..=0b0011_1111_1111_1111 => dest.put_u16_le(((n as u16) << 2) | 0b01),
605        0..=0b0011_1111_1111_1111_1111_1111_1111_1111 => dest.put_u32_le(((n as u32) << 2) | 0b10),
606        _ => {
607            let bytes_needed = 8 - n.leading_zeros() / 8;
608            assert!(
609                bytes_needed >= 4,
610                "Previous match arm matches anyting less than 2^30; qed"
611            );
612            dest.put_u8(0b11 + ((bytes_needed - 4) << 2) as u8);
613            let mut v = n;
614            for _ in 0..bytes_needed {
615                dest.put_u8(v as u8);
616                v >>= 8;
617            }
618            assert_eq!(
619                v, 0,
620                "shifted sufficient bits right to lead only leading zeros; qed"
621            )
622        }
623    }
624}
625
626#[cfg(test)]
627mod tests {
628    use super::*;
629    use codec::Encode;
630    use core::mem::size_of;
631    use scale_info::{meta_type, Registry, TypeInfo};
632    use serde_json::to_value;
633
634    #[test]
635    fn primitive_u8() -> Result<()> {
636        let mut out = [0u8];
637        to_bytes(&mut out[..], &123u8)?;
638
639        let expected = [123];
640
641        assert_eq!(out, expected);
642        Ok(())
643    }
644
645    #[test]
646    fn primitive_u16() -> Result<()> {
647        const INPUT: u16 = 0xFF_EE;
648        let mut out = [0u8; size_of::<u16>()];
649        let expected = INPUT.encode();
650
651        to_bytes(out.as_mut(), &INPUT)?;
652
653        assert_eq!(out.as_ref(), expected);
654        Ok(())
655    }
656
657    #[test]
658    fn primitive_u32() -> Result<()> {
659        const INPUT: u32 = 0xFF_EE_DD_CC;
660        let mut out = [0u8; size_of::<u32>()];
661        let expected = INPUT.encode();
662
663        to_bytes(out.as_mut(), &INPUT)?;
664
665        assert_eq!(out.as_ref(), expected);
666        Ok(())
667    }
668
669    #[test]
670    fn primitive_u64() -> Result<()> {
671        const INPUT: u64 = 0xFF_EE_DD_CC__BB_AA_99_88;
672        let mut out = [0u8; size_of::<u64>()];
673        let expected = INPUT.encode();
674
675        to_bytes(out.as_mut(), &INPUT)?;
676
677        assert_eq!(out.as_mut(), expected);
678        Ok(())
679    }
680
681    #[test]
682    fn primitive_i16() -> Result<()> {
683        const INPUT: i16 = i16::MIN;
684        let mut out = [0u8; size_of::<i16>()];
685        let expected = INPUT.encode();
686
687        to_bytes(out.as_mut(), &INPUT)?;
688
689        assert_eq!(out.as_mut(), expected);
690        Ok(())
691    }
692
693    #[test]
694    fn primitive_i32() -> Result<()> {
695        const INPUT: i32 = i32::MIN;
696        let mut out = [0u8; size_of::<i32>()];
697        let expected = INPUT.encode();
698
699        to_bytes(out.as_mut(), &INPUT)?;
700
701        assert_eq!(out.as_mut(), expected);
702        Ok(())
703    }
704
705    #[test]
706    fn primitive_i64() -> Result<()> {
707        const INPUT: i64 = i64::MIN;
708        let mut out = [0u8; size_of::<i64>()];
709        let expected = INPUT.encode();
710
711        to_bytes(out.as_mut(), &INPUT)?;
712
713        assert_eq!(out.as_mut(), expected);
714        Ok(())
715    }
716
717    #[test]
718    fn primitive_bool() -> Result<()> {
719        const INPUT: bool = true;
720        let mut out = [0u8];
721        let expected = INPUT.encode();
722
723        to_bytes(out.as_mut(), &INPUT)?;
724
725        assert_eq!(out.as_mut(), expected);
726        Ok(())
727    }
728
729    #[test]
730    fn str() -> Result<()> {
731        const INPUT: &str = "ac orci phasellus egestas tellus rutrum tellus pellentesque";
732        let mut out = Vec::<u8>::new();
733        let expected = INPUT.encode();
734
735        to_bytes(&mut out, &INPUT)?;
736
737        assert_eq!(out, expected);
738        Ok(())
739    }
740
741    #[test]
742    fn bytes() -> Result<()> {
743        const INPUT: &[u8] = b"dictumst quisque sagittis purus sit amet volutpat consequat";
744        let mut out = Vec::<u8>::new();
745        let expected = INPUT.encode();
746
747        to_bytes(&mut out, &INPUT)?;
748
749        assert_eq!(out, expected);
750        Ok(())
751    }
752
753    #[test]
754    fn tuple_simple() -> Result<()> {
755        const INPUT: (u8, bool, u64) = (0xD0, false, u64::MAX);
756        let mut out = Vec::<u8>::new();
757        let expected = INPUT.encode();
758
759        to_bytes(&mut out, &INPUT)?;
760
761        assert_eq!(out, expected);
762        Ok(())
763    }
764
765    #[test]
766    fn enum_simple() -> Result<()> {
767        #[derive(Serialize, Encode)]
768        enum X {
769            _A,
770            B,
771        }
772
773        const INPUT: X = X::B;
774        let mut out = Vec::<u8>::new();
775        let expected = INPUT.encode();
776
777        to_bytes(&mut out, &INPUT)?;
778
779        assert_eq!(out, expected);
780        Ok(())
781    }
782
783    #[test]
784    fn tuple_enum_mix() -> Result<()> {
785        #[derive(Serialize, Encode)]
786        enum X {
787            A,
788            B,
789        }
790
791        let input: (Option<()>, Option<String>, X, X) = (None, Some("hello".into()), X::A, X::B);
792        let mut out = Vec::<u8>::new();
793        let expected = input.encode();
794
795        to_bytes(&mut out, &input)?;
796
797        assert_eq!(out, expected);
798        Ok(())
799    }
800
801    #[test]
802    fn struct_simple() -> Result<()> {
803        #[derive(Serialize, Encode)]
804        struct Foo {
805            a: Bar,
806            b: Option<Baz>,
807        }
808        #[derive(Serialize, Encode)]
809        struct Bar(u8);
810        #[derive(Serialize, Encode)]
811        struct Baz(String, u16);
812
813        let input = Foo {
814            a: Bar(0xFF),
815            b: Some(Baz("lol".into(), u16::MAX)),
816        };
817        let mut out = Vec::<u8>::new();
818        let expected = input.encode();
819
820        to_bytes(&mut out, &input)?;
821
822        assert_eq!(out, expected);
823        Ok(())
824    }
825
826    #[test]
827    fn vec_simple() -> Result<()> {
828        let input: Vec<String> = vec!["hello".into(), "beautiful".into(), "people".into()];
829        let mut out = Vec::<u8>::new();
830        let expected = input.encode();
831
832        to_bytes(&mut out, &input)?;
833
834        assert_eq!(out, expected);
835        Ok(())
836    }
837
838    #[test]
839    fn struct_mix() -> Result<()> {
840        #[derive(Serialize, Encode)]
841        struct Foo<'a> {
842            a: Vec<String>,
843            b: (Bar<'a>, Bar<'a>, Bar<'a>),
844        }
845        #[derive(Serialize, Encode)]
846        enum Bar<'a> {
847            A { thing: &'a str },
848            B(Baz),
849            C(BTreeMap<String, bool>, i64),
850        }
851        #[derive(Serialize, Encode)]
852        struct Baz;
853
854        let input = Foo {
855            a: vec!["hello".into(), "beautiful".into(), "people".into()],
856            b: (
857                Bar::A { thing: "barbarbar" },
858                Bar::B(Baz),
859                Bar::C(
860                    {
861                        let mut h = BTreeMap::new();
862                        h.insert("key".into(), false);
863                        h
864                    },
865                    i64::MIN,
866                ),
867            ),
868        };
869        let mut out = Vec::<u8>::new();
870        let expected = input.encode();
871
872        to_bytes(&mut out, &input)?;
873
874        assert_eq!(out, expected);
875        Ok(())
876    }
877
878    fn register<T>(_ty: &T) -> (TypeId, PortableRegistry)
879    where
880        T: TypeInfo + 'static,
881    {
882        let mut reg = Registry::new();
883        let sym = reg.register_type(&meta_type::<T>());
884        (sym.id(), reg.into())
885    }
886
887    #[test]
888    fn json_simple() -> Result<()> {
889        #[derive(Debug, Serialize, Encode, TypeInfo)]
890        struct Foo {
891            a: Bar,
892            b: Option<Baz>,
893        }
894        #[derive(Debug, Serialize, Encode, TypeInfo)]
895        struct Bar(u8);
896        #[derive(Debug, Serialize, Encode, TypeInfo)]
897        struct Baz(String, i32);
898
899        let input = Foo {
900            a: Bar(0xFF),
901            b: Some(Baz("lol".into(), i32::MIN)),
902        };
903        let mut out = Vec::<u8>::new();
904        let expected = input.encode();
905        let (id, reg) = register(&input);
906
907        let json_input = to_value(&input).unwrap();
908        to_bytes_with_info(&mut out, &json_input, Some((&reg, id)))?;
909
910        assert_eq!(out, expected);
911        Ok(())
912    }
913
914    #[test]
915    fn json_mix() -> Result<()> {
916        #[derive(Debug, Serialize, Encode, TypeInfo)]
917        struct Foo<'a> {
918            a: Vec<String>,
919            b: (Bar<'a>, Bar<'a>, Bar<'a>),
920        }
921        #[derive(Debug, Serialize, Encode, TypeInfo)]
922        enum Bar<'a> {
923            A { thing: &'a str },
924            B(Baz),
925            C(BTreeMap<String, bool>, i64),
926        }
927        #[derive(Debug, Serialize, Encode, TypeInfo)]
928        struct Baz;
929
930        let input = Foo {
931            a: vec!["hello".into(), "beautiful".into(), "people".into()],
932            b: (
933                Bar::A { thing: "barbarbar" },
934                Bar::B(Baz),
935                Bar::C(
936                    {
937                        let mut h = BTreeMap::new();
938                        h.insert("key1".into(), false);
939                        h.insert("key2".into(), true);
940                        h
941                    },
942                    i64::MIN,
943                ),
944            ),
945        };
946        let mut out = Vec::<u8>::new();
947        let expected = input.encode();
948        let (id, reg) = register(&input);
949
950        let json_input = to_value(&input).unwrap();
951        to_bytes_with_info(&mut out, &json_input, Some((&reg, id)))?;
952
953        assert_eq!(out, expected);
954        Ok(())
955    }
956
957    #[test]
958    fn json_mix2() -> Result<()> {
959        #[derive(Debug, Encode, Serialize, TypeInfo)]
960        enum Bar {
961            This,
962            That(i16),
963        }
964        #[derive(Debug, Encode, Serialize, TypeInfo)]
965        struct Baz(String);
966        #[derive(Debug, Encode, Serialize, TypeInfo)]
967        struct Foo {
968            bar: Vec<Bar>,
969            baz: Option<Baz>,
970            lol: &'static [u8],
971        }
972        let input = Foo {
973            bar: [Bar::That(i16::MAX), Bar::This].into(),
974            baz: Some(Baz("lorem ipsum".into())),
975            lol: b"\0xFFsome stuff\0x00",
976        };
977        let mut out = Vec::<u8>::new();
978        let expected = input.encode();
979        let (id, reg) = register(&input);
980
981        let json_input = to_value(&input).unwrap();
982        to_bytes_with_info(&mut out, &json_input, Some((&reg, id)))?;
983
984        assert_eq!(out, expected);
985        Ok(())
986    }
987}