scale_serialization/
value.rs

1use crate::{EnumVariant, SpecificType};
2use alloc::{collections::BTreeMap, vec::Vec};
3use bytes::{Buf, Bytes};
4use core::{convert::TryInto, str};
5use scale_info::{prelude::*, PortableRegistry, TypeDefPrimitive as Primitive};
6use serde::ser::{SerializeMap, SerializeSeq, SerializeTuple, SerializeTupleStruct};
7use serde::Serialize;
8
9type Type = scale_info::Type<scale_info::form::PortableForm>;
10type TypeId = u32;
11type TypeDef = scale_info::TypeDef<scale_info::form::PortableForm>;
12
13/// A container for SCALE encoded data that can serialize types directly
14/// with the help of a type registry and without using an intermediate representation.
15pub struct Value<'a> {
16    data: Bytes,
17    ty_id: TypeId,
18    registry: &'a PortableRegistry,
19}
20
21impl<'a> Value<'a> {
22    pub fn new(data: impl Into<Bytes>, ty_id: u32, registry: &'a PortableRegistry) -> Self {
23        Value {
24            data: data.into(),
25            ty_id,
26            registry,
27        }
28    }
29
30    fn new_value(&self, data: &mut Bytes, ty_id: TypeId) -> Self {
31        let size = self.ty_len(data.chunk(), ty_id);
32        Value::new(data.copy_to_bytes(size), ty_id, self.registry)
33    }
34
35    #[inline]
36    fn resolve(&self, ty: TypeId) -> &'a Type {
37        self.registry.resolve(ty).expect("in registry")
38    }
39
40    fn ty_len(&self, data: &[u8], ty: TypeId) -> usize {
41        match self.resolve(ty).type_def() {
42            TypeDef::Primitive(p) => match p {
43                Primitive::U8 => mem::size_of::<u8>(),
44                Primitive::U16 => mem::size_of::<u16>(),
45                Primitive::U32 => mem::size_of::<u32>(),
46                Primitive::U64 => mem::size_of::<u64>(),
47                Primitive::U128 => mem::size_of::<u128>(),
48                Primitive::I8 => mem::size_of::<i8>(),
49                Primitive::I16 => mem::size_of::<i16>(),
50                Primitive::I32 => mem::size_of::<i32>(),
51                Primitive::I64 => mem::size_of::<i64>(),
52                Primitive::I128 => mem::size_of::<i128>(),
53                Primitive::Bool => mem::size_of::<bool>(),
54                Primitive::Char => mem::size_of::<char>(),
55                Primitive::Str => {
56                    let (l, p_size) = sequence_len(data);
57                    l + p_size
58                }
59                _ => unimplemented!(),
60            },
61            TypeDef::Composite(c) => c
62                .fields()
63                .iter()
64                .fold(0, |c, f| c + self.ty_len(&data[c..], f.ty().id())),
65            TypeDef::Variant(e) => {
66                let var = e
67                    .variants()
68                    .iter()
69                    .find(|v| v.index() == data[0])
70                    .expect("variant");
71
72                if var.fields().is_empty() {
73                    1 // unit variant
74                } else {
75                    var.fields()
76                        .iter()
77                        .fold(1, |c, f| c + self.ty_len(&data[c..], f.ty().id()))
78                }
79            }
80            TypeDef::Sequence(s) => {
81                let (len, prefix_size) = sequence_len(data);
82                let ty_id = s.type_param().id();
83                (0..len).fold(prefix_size, |c, _| c + self.ty_len(&data[c..], ty_id))
84            }
85            TypeDef::Array(a) => a.len().try_into().unwrap(),
86            TypeDef::Tuple(t) => t.fields().len(),
87            TypeDef::Compact(_) => compact_len(data),
88            TypeDef::BitSequence(_) => unimplemented!(),
89        }
90    }
91}
92
93impl<'a> Serialize for Value<'a> {
94    fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
95    where
96        S: serde::Serializer,
97    {
98        let mut data = self.data.clone();
99        let ty = self.resolve(self.ty_id);
100
101        use SpecificType::*;
102        match (ty, self.registry).into() {
103            Bool => ser.serialize_bool(data.get_u8() != 0),
104            U8 => ser.serialize_u8(data.get_u8()),
105            U16 => ser.serialize_u16(data.get_u16_le()),
106            U32 => ser.serialize_u32(data.get_u32_le()),
107            U64 => ser.serialize_u64(data.get_u64_le()),
108            U128 => ser.serialize_u128(data.get_u128_le()),
109            I8 => ser.serialize_i8(data.get_i8()),
110            I16 => ser.serialize_i16(data.get_i16_le()),
111            I32 => ser.serialize_i32(data.get_i32_le()),
112            I64 => ser.serialize_i64(data.get_i64_le()),
113            I128 => ser.serialize_i128(data.get_i128_le()),
114            Bytes => ser.serialize_bytes(data.chunk()),
115            Char => ser.serialize_char(char::from_u32(data.get_u32_le()).unwrap()),
116            Str => {
117                let (_, s) = sequence_len(data.chunk());
118                data.advance(s);
119                ser.serialize_str(str::from_utf8(data.chunk()).unwrap())
120            }
121            Sequence(ty) => {
122                let (len, p_size) = sequence_len(data.chunk());
123                data.advance(p_size);
124
125                let mut seq = ser.serialize_seq(Some(len))?;
126                for _ in 0..len {
127                    seq.serialize_element(&self.new_value(&mut data, ty))?;
128                }
129                seq.end()
130            }
131            Map(ty_k, ty_v) => {
132                let (len, p_size) = sequence_len(data.chunk());
133                data.advance(p_size);
134
135                let mut state = ser.serialize_map(Some(len))?;
136                for _ in 0..len {
137                    let key = self.new_value(&mut data, ty_k);
138                    let val = self.new_value(&mut data, ty_v);
139                    state.serialize_entry(&key, &val)?;
140                }
141                state.end()
142            }
143            Tuple(t) => {
144                let mut state = ser.serialize_tuple(t.len())?;
145                for i in 0..t.len() {
146                    state.serialize_element(&self.new_value(&mut data, t.type_id(i)))?;
147                }
148                state.end()
149            }
150            Struct(fields) => {
151                let mut state = ser.serialize_map(Some(fields.len()))?;
152                for (name, ty) in fields {
153                    state.serialize_key(&name)?;
154                    state.serialize_value(&self.new_value(&mut data, ty))?;
155                }
156                state.end()
157            }
158            StructUnit => ser.serialize_unit(),
159            StructNewType(ty) => ser.serialize_newtype_struct("", &self.new_value(&mut data, ty)),
160            StructTuple(fields) => {
161                let mut state = ser.serialize_tuple_struct("", fields.len())?;
162                for ty in fields {
163                    state.serialize_field(&self.new_value(&mut data, ty))?;
164                }
165                state.end()
166            }
167            ty @ Variant(_, _, _) => {
168                let variant = &ty.pick(data.get_u8());
169                match variant.into() {
170                    EnumVariant::OptionNone => ser.serialize_none(),
171                    EnumVariant::OptionSome(ty) => {
172                        ser.serialize_some(&self.new_value(&mut data, ty))
173                    }
174                    EnumVariant::Unit(_idx, name) => ser.serialize_str(name),
175                    EnumVariant::NewType(_idx, name, ty) => {
176                        let mut s = ser.serialize_map(Some(1))?;
177                        s.serialize_key(name)?;
178                        s.serialize_value(&self.new_value(&mut data, ty))?;
179                        s.end()
180                    }
181
182                    EnumVariant::Tuple(_idx, name, fields) => {
183                        let mut s = ser.serialize_map(Some(1))?;
184                        s.serialize_key(name)?;
185                        s.serialize_value(
186                            &fields
187                                .iter()
188                                .map(|ty| self.new_value(&mut data, *ty))
189                                .collect::<Vec<_>>(),
190                        )?;
191                        s.end()
192                    }
193                    EnumVariant::Struct(_idx, name, fields) => {
194                        let mut s = ser.serialize_map(Some(1))?;
195                        s.serialize_key(name)?;
196                        s.serialize_value(&fields.iter().fold(
197                            BTreeMap::new(),
198                            |mut m, (name, ty)| {
199                                m.insert(*name, self.new_value(&mut data, *ty));
200                                m
201                            },
202                        ))?;
203                        s.end()
204                    }
205                }
206            }
207        }
208    }
209}
210
211#[inline]
212fn compact_len(data: &[u8]) -> usize {
213    match data[0] % 0b100 {
214        0 => 1,
215        1 => 2,
216        2 => 4,
217        _ => todo!(),
218    }
219}
220
221fn sequence_len(data: &[u8]) -> (usize, usize) {
222    // need to peek at the data to know the length of sequence
223    // first byte(s) gives us a hint of the(compact encoded) length
224    // https://substrate.dev/docs/en/knowledgebase/advanced/codec#compactgeneral-integers
225    let len = compact_len(data);
226    (
227        match len {
228            1 => (data[0] >> 2).into(),
229            2 => u16::from_le_bytes([(data[0] >> 2), data[1]]).into(),
230            4 => u32::from_le_bytes([(data[0] >> 2), data[1], data[2], data[3]])
231                .try_into()
232                .unwrap(),
233
234            _ => todo!(),
235        },
236        len,
237    )
238}
239
240impl<'reg> AsRef<[u8]> for Value<'reg> {
241    fn as_ref(&self) -> &[u8] {
242        self.data.as_ref()
243    }
244}
245
246#[cfg(feature = "codec")]
247impl<'reg> codec::Encode for Value<'reg> {
248    fn size_hint(&self) -> usize {
249        self.data.len()
250    }
251    fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
252        f(self.data.as_ref())
253    }
254}
255
256impl<'reg> core::fmt::Debug for Value<'reg> {
257    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
258        write!(
259            f,
260            "Value {{ data: {:?}, type({}): {:?} }}",
261            self.data,
262            self.ty_id,
263            self.registry.resolve(self.ty_id).unwrap().type_def()
264        )
265    }
266}
267
268#[cfg(feature = "json")]
269impl<'reg> core::fmt::Display for Value<'reg> {
270    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
271        write!(
272            f,
273            "{}",
274            serde_json::to_string(self).map_err(|_| fmt::Error)?
275        )
276    }
277}
278
279#[cfg(feature = "json")]
280impl<'reg> Into<crate::JsonValue> for Value<'reg> {
281    fn into(self) -> crate::JsonValue {
282        serde_json::value::to_value(self).unwrap()
283    }
284}
285
286#[cfg(test)]
287mod tests {
288    use alloc::collections::BTreeMap;
289
290    use super::*;
291    use anyhow::Error;
292    use codec::Encode;
293    use scale_info::{
294        meta_type,
295        prelude::{string::String, vec::Vec},
296        Registry, TypeInfo,
297    };
298    use serde_json::to_value;
299
300    fn register<T>(_ty: &T) -> (u32, PortableRegistry)
301    where
302        T: TypeInfo + 'static,
303    {
304        let mut reg = Registry::new();
305        let sym = reg.register_type(&meta_type::<T>());
306        (sym.id(), reg.into())
307    }
308
309    #[cfg(feature = "json")]
310    #[test]
311    fn display_as_json() {
312        #[derive(Encode, TypeInfo)]
313        struct Foo {
314            bar: String,
315        }
316        let in_value = Foo { bar: "BAZ".into() };
317
318        let data = in_value.encode();
319        let (id, reg) = register(&in_value);
320        let out_value = Value::new(data, id, &reg).to_string();
321
322        assert_eq!("{\"bar\":\"BAZ\"}", out_value);
323    }
324
325    #[cfg(feature = "codec")]
326    #[test]
327    fn encodable() {
328        let input = u8::MAX;
329        let (ty, reg) = register(&input);
330        let value = Value::new(b"1234".as_ref(), ty, &reg);
331
332        let expected: &[u8] = value.as_ref();
333        assert_eq!(value.encode(), expected);
334    }
335
336    #[test]
337    fn serialize_u8() -> Result<(), Error> {
338        let in_value = u8::MAX;
339        let data = in_value.encode();
340        let (id, reg) = register(&in_value);
341
342        let out_value = Value::new(data, id, &reg);
343
344        assert_eq!(to_value(out_value)?, to_value(in_value)?);
345        Ok(())
346    }
347
348    #[test]
349    fn serialize_u16() -> Result<(), Error> {
350        let in_value = u16::MAX;
351        let data = in_value.encode();
352        let (id, reg) = register(&in_value);
353
354        let out_value = Value::new(data, id, &reg);
355
356        assert_eq!(to_value(out_value)?, to_value(in_value)?);
357        Ok(())
358    }
359
360    #[test]
361    fn serialize_u32() -> Result<(), Error> {
362        let in_value = u32::MAX;
363        let data = in_value.encode();
364        let (id, reg) = register(&in_value);
365
366        let out_value = Value::new(data, id, &reg);
367
368        assert_eq!(to_value(out_value)?, to_value(in_value)?);
369        Ok(())
370    }
371
372    #[test]
373    fn serialize_u64() -> Result<(), Error> {
374        let in_value = u64::MAX;
375        let data = in_value.encode();
376        let (id, reg) = register(&in_value);
377
378        let out_value = Value::new(data, id, &reg);
379
380        assert_eq!(to_value(out_value)?, to_value(in_value)?);
381        Ok(())
382    }
383
384    #[test]
385    fn serialize_i16() -> Result<(), Error> {
386        let in_value = i16::MAX;
387        let data = in_value.encode();
388        let (id, reg) = register(&in_value);
389
390        let out_value = Value::new(data, id, &reg);
391
392        assert_eq!(to_value(out_value)?, to_value(in_value)?);
393        Ok(())
394    }
395
396    #[test]
397    fn serialize_i32() -> Result<(), Error> {
398        let in_value = i32::MAX;
399        let data = in_value.encode();
400        let (id, reg) = register(&in_value);
401
402        let out_value = Value::new(data, id, &reg);
403
404        assert_eq!(to_value(out_value)?, to_value(in_value)?);
405        Ok(())
406    }
407
408    #[test]
409    fn serialize_i64() -> Result<(), Error> {
410        let in_value = i64::MAX;
411        let data = in_value.encode();
412        let (id, reg) = register(&in_value);
413
414        let out_value = Value::new(data, id, &reg);
415
416        assert_eq!(to_value(out_value)?, to_value(in_value)?);
417        Ok(())
418    }
419
420    #[test]
421    fn serialize_bool() -> Result<(), Error> {
422        let in_value = true;
423        let data = in_value.encode();
424        let (id, reg) = register(&in_value);
425
426        let out_value = Value::new(data, id, &reg);
427
428        assert_eq!(to_value(out_value)?, to_value(in_value)?);
429        Ok(())
430    }
431
432    // `char` not supported?
433    // #[test]
434    // fn serialize_char() -> Result<(), Error> {
435    //     let extract_value = '⚖';
436    //     let data = extract_value.encode();
437    //     let info = char::type_info();
438    //     let val = Value::new(data, info, reg);
439    //     assert_eq!(to_value(val)?, to_value(extract_value)?);
440    //     Ok(())
441    // }
442
443    #[test]
444    fn serialize_u8array() -> Result<(), Error> {
445        let in_value: Vec<u8> = [2u8, u8::MAX].into();
446        let data = in_value.encode();
447        let (id, reg) = register(&in_value);
448
449        let out_value = Value::new(data, id, &reg);
450
451        assert_eq!(to_value(out_value)?, to_value(in_value)?);
452        Ok(())
453    }
454
455    #[test]
456    fn serialize_u16array() -> Result<(), Error> {
457        let in_value: Vec<u16> = [2u16, u16::MAX].into();
458        let data = in_value.encode();
459        let (id, reg) = register(&in_value);
460
461        let out_value = Value::new(data, id, &reg);
462
463        assert_eq!(to_value(out_value)?, to_value(in_value)?);
464        Ok(())
465    }
466
467    #[test]
468    fn serialize_u32array() -> Result<(), Error> {
469        let in_value: Vec<u32> = [2u32, u32::MAX].into();
470        let data = in_value.encode();
471        let (id, reg) = register(&in_value);
472
473        let out_value = Value::new(data, id, &reg);
474
475        assert_eq!(to_value(out_value)?, to_value(in_value)?);
476        Ok(())
477    }
478
479    #[test]
480    fn serialize_tuple() -> Result<(), Error> {
481        let in_value: (i64, Vec<String>, bool) = (
482            i64::MIN,
483            vec!["hello".into(), "big".into(), "world".into()],
484            true,
485        );
486        let data = in_value.encode();
487        let (id, reg) = register(&in_value);
488
489        let out_value = Value::new(data, id, &reg);
490
491        assert_eq!(to_value(out_value)?, to_value(in_value)?);
492        Ok(())
493    }
494
495    #[test]
496    fn serialize_simple_u32struct() -> Result<(), Error> {
497        #[derive(Encode, Serialize, TypeInfo)]
498        struct Foo {
499            bar: u32,
500            baz: u32,
501        }
502        let in_value = Foo {
503            bar: 123,
504            baz: u32::MAX,
505        };
506        let data = in_value.encode();
507        let (id, reg) = register(&in_value);
508
509        let out_value = Value::new(data, id, &reg);
510
511        assert_eq!(to_value(out_value)?, to_value(in_value)?);
512        Ok(())
513    }
514
515    #[test]
516    fn serialize_simple_u8struct() -> Result<(), Error> {
517        #[derive(Encode, Serialize, TypeInfo)]
518        struct Foo {
519            bar: u8,
520            baz: u8,
521        }
522        let in_value = Foo {
523            bar: 123,
524            baz: u8::MAX,
525        };
526        let data = in_value.encode();
527        let (id, reg) = register(&in_value);
528
529        let out_value = Value::new(data, id, &reg);
530
531        assert_eq!(to_value(out_value)?, to_value(in_value)?);
532        Ok(())
533    }
534
535    #[test]
536    fn serialize_simple_u64struct() -> Result<(), Error> {
537        #[derive(Encode, Serialize, TypeInfo)]
538        struct Foo {
539            bar: u64,
540            baz: u64,
541        }
542        let in_value = Foo {
543            bar: 123,
544            baz: u64::MAX,
545        };
546        let data = in_value.encode();
547        let (id, reg) = register(&in_value);
548
549        let out_value = Value::new(data, id, &reg);
550
551        assert_eq!(to_value(out_value)?, to_value(in_value)?);
552        Ok(())
553    }
554
555    #[test]
556    fn serialize_map() -> Result<(), Error> {
557        let in_value = {
558            let mut m = BTreeMap::<String, i32>::new();
559            m.insert("foo".into(), i32::MAX);
560            m.insert("bar".into(), i32::MIN);
561            m
562        };
563
564        let data = in_value.encode();
565        let (id, reg) = register(&in_value);
566
567        let out_value = Value::new(data, id, &reg);
568
569        assert_eq!(to_value(out_value)?, to_value(in_value)?);
570        Ok(())
571    }
572
573    #[test]
574    fn serialize_complex_struct_with_enum() -> Result<(), Error> {
575        #[derive(Encode, Serialize, TypeInfo)]
576        enum Bar {
577            This,
578            That(i16),
579        }
580        #[derive(Encode, Serialize, TypeInfo)]
581        struct Baz(String);
582        #[derive(Encode, Serialize, TypeInfo)]
583        struct Foo {
584            bar: Vec<Bar>,
585            baz: Option<Baz>,
586            lol: &'static [u8],
587        }
588        let in_value = Foo {
589            bar: [Bar::That(i16::MAX), Bar::This].into(),
590            baz: Some(Baz("aliquam malesuada bibendum arcu vitae".into())),
591            lol: b"\0xFFsome stuff\0x00",
592        };
593        let data = in_value.encode();
594        let (id, reg) = register(&in_value);
595
596        let out_value = Value::new(data, id, &reg);
597
598        assert_eq!(to_value(out_value)?, to_value(in_value)?);
599        Ok(())
600    }
601
602    #[test]
603    fn serialize_tuple_struct() -> Result<(), Error> {
604        #[derive(Encode, Serialize, TypeInfo)]
605        struct Foo<'a>([u8; 4], (bool, Option<()>), Baz<'a>, Baz<'a>);
606
607        #[derive(Encode, Serialize, TypeInfo)]
608        struct Bar;
609
610        #[derive(Encode, Serialize, TypeInfo)]
611        enum Baz<'a> {
612            A(Bar),
613            B { bb: &'a str },
614        }
615
616        let in_value = Foo(
617            [1, 2, 3, 4],
618            (false, None),
619            Baz::A(Bar),
620            Baz::B { bb: "lol" },
621        );
622        let data = in_value.encode();
623        let (id, reg) = register(&in_value);
624
625        let out_value = Value::new(data, id, &reg);
626
627        assert_eq!(to_value(out_value)?, to_value(in_value)?);
628        Ok(())
629    }
630}