scale_value/serde_impls/
serializer.rs

1// Copyright (C) 2022-2023 Parity Technologies (UK) Ltd. (admin@parity.io)
2// This file is a part of the scale-value crate.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//         http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16//! This [`Serializer`] impl allows types implementing `Serialize` to be converted
17//! into [`Value`]s.
18
19use crate::prelude::*;
20use crate::{Composite, Primitive, Value, ValueDef};
21use serde::{
22    ser::{
23        SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,
24        SerializeTupleStruct, SerializeTupleVariant,
25    },
26    Serializer,
27};
28
29/// This struct implements [`Serializer`] and knows how to map from the serde data model to a [`Value`] type.
30pub struct ValueSerializer;
31
32/// An error that can occur when attempting to serialize a type into a [`Value`].
33#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
34pub enum SerializerError {
35    /// Some custom error string.
36    #[error("Custom error: {0}")]
37    Custom(String),
38    /// SCALE does not support floating point values, and so we'll hit this error if we try to
39    /// encode any floats.
40    #[error(
41        "Floats do not have a SCALE compatible representation, and so cannot be serialized to Values"
42    )]
43    CannotSerializeFloats,
44    /// SCALE encoding is only designed to map from statically known structs to bytes. We use field names
45    /// to figure out this mapping between named composite types and structs, so we don't support encoding
46    /// maps with non-string keys into [`Value`]s.
47    #[error("Map keys must be strings or string-like")]
48    MapKeyMustBeStringlike,
49}
50
51impl serde::ser::Error for SerializerError {
52    fn custom<T>(msg: T) -> Self
53    where
54        T: core::fmt::Display,
55    {
56        SerializerError::Custom(msg.to_string())
57    }
58}
59
60macro_rules! serialize_prim {
61    ($name:ident => $method:ident($ty:ident)) => {
62        fn $name(self, v: $ty) -> Result<Self::Ok, Self::Error> {
63            Ok(Value::$method(v.into()))
64        }
65    };
66}
67
68impl Serializer for ValueSerializer {
69    type Ok = Value<()>;
70    type Error = SerializerError;
71
72    type SerializeSeq = UnnamedCompositeSerializer;
73    type SerializeTuple = UnnamedCompositeSerializer;
74    type SerializeTupleStruct = UnnamedCompositeSerializer;
75    type SerializeTupleVariant = UnnamedCompositeSerializer;
76    type SerializeMap = NamedCompositeSerializer;
77    type SerializeStruct = NamedCompositeSerializer;
78    type SerializeStructVariant = NamedCompositeSerializer;
79
80    serialize_prim!(serialize_bool => bool(bool));
81    serialize_prim!(serialize_i8 => i128(i8));
82    serialize_prim!(serialize_i16 => i128(i16));
83    serialize_prim!(serialize_i32 => i128(i32));
84    serialize_prim!(serialize_i64 => i128(i64));
85    serialize_prim!(serialize_i128 => i128(i128));
86    serialize_prim!(serialize_u8 => u128(u8));
87    serialize_prim!(serialize_u16 => u128(u16));
88    serialize_prim!(serialize_u32 => u128(u32));
89    serialize_prim!(serialize_u64 => u128(u64));
90    serialize_prim!(serialize_u128 => u128(u128));
91    serialize_prim!(serialize_char => char(char));
92
93    fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
94        Err(SerializerError::CannotSerializeFloats)
95    }
96    fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
97        Err(SerializerError::CannotSerializeFloats)
98    }
99
100    fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
101        Ok(Value::string(v.to_string()))
102    }
103
104    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
105        let bytes = v.iter().map(|&b| Value::u128(b as u128));
106        Ok(Value::unnamed_composite(bytes))
107    }
108
109    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
110        Ok(Value::variant("None".to_string(), Composite::Unnamed(Vec::new())))
111    }
112
113    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
114    where
115        T: serde::Serialize + ?Sized,
116    {
117        let inner = value.serialize(ValueSerializer)?;
118        Ok(Value::variant("Some".to_string(), Composite::Unnamed(vec![inner])))
119    }
120
121    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
122        Ok(Value::unnamed_composite(Vec::new()))
123    }
124
125    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
126        Ok(Value::unnamed_composite(Vec::new()))
127    }
128
129    fn serialize_unit_variant(
130        self,
131        _name: &'static str,
132        _variant_index: u32,
133        variant: &'static str,
134    ) -> Result<Self::Ok, Self::Error> {
135        Ok(Value::variant(variant.to_string(), Composite::Unnamed(Vec::new())))
136    }
137
138    fn serialize_newtype_struct<T>(
139        self,
140        _name: &'static str,
141        value: &T,
142    ) -> Result<Self::Ok, Self::Error>
143    where
144        T: serde::Serialize + ?Sized,
145    {
146        let inner = value.serialize(ValueSerializer)?;
147        Ok(Value::unnamed_composite(vec![inner]))
148    }
149
150    fn serialize_newtype_variant<T>(
151        self,
152        _name: &'static str,
153        _variant_index: u32,
154        variant: &'static str,
155        value: &T,
156    ) -> Result<Self::Ok, Self::Error>
157    where
158        T: serde::Serialize + ?Sized,
159    {
160        let inner = value.serialize(ValueSerializer)?;
161        Ok(Value::variant(variant.to_string(), Composite::Unnamed(vec![inner])))
162    }
163
164    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
165        Ok(Self::SerializeSeq::new_composite())
166    }
167
168    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
169        Ok(Self::SerializeTuple::new_composite())
170    }
171
172    fn serialize_tuple_struct(
173        self,
174        _name: &'static str,
175        _len: usize,
176    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
177        Ok(Self::SerializeTupleStruct::new_composite())
178    }
179
180    fn serialize_tuple_variant(
181        self,
182        _name: &'static str,
183        _variant_index: u32,
184        variant: &'static str,
185        _len: usize,
186    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
187        Ok(Self::SerializeTupleVariant::new_variant(variant.into()))
188    }
189
190    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
191        Ok(Self::SerializeMap::new_composite())
192    }
193
194    fn serialize_struct(
195        self,
196        _name: &'static str,
197        _len: usize,
198    ) -> Result<Self::SerializeStruct, Self::Error> {
199        Ok(Self::SerializeStruct::new_composite())
200    }
201
202    fn serialize_struct_variant(
203        self,
204        _name: &'static str,
205        _variant_index: u32,
206        variant: &'static str,
207        _len: usize,
208    ) -> Result<Self::SerializeStructVariant, Self::Error> {
209        Ok(Self::SerializeStructVariant::new_variant(variant.into()))
210    }
211}
212
213// Serializes anything that should end up as an unnamed composite value:
214pub struct UnnamedCompositeSerializer {
215    // Only present if the thing should be a variant:
216    variant_name: Option<String>,
217    values: Vec<Value<()>>,
218}
219
220impl UnnamedCompositeSerializer {
221    fn new_composite() -> UnnamedCompositeSerializer {
222        UnnamedCompositeSerializer { variant_name: None, values: Vec::new() }
223    }
224
225    fn new_variant(variant_name: String) -> UnnamedCompositeSerializer {
226        UnnamedCompositeSerializer { variant_name: Some(variant_name), values: Vec::new() }
227    }
228
229    fn serialize_element<T>(&mut self, value: &T) -> Result<(), SerializerError>
230    where
231        T: serde::Serialize + ?Sized,
232    {
233        let inner = value.serialize(ValueSerializer)?;
234        self.values.push(inner);
235        Ok(())
236    }
237
238    fn end(self) -> Result<Value<()>, SerializerError> {
239        match self.variant_name {
240            Some(name) => Ok(Value::variant(name, Composite::Unnamed(self.values))),
241            None => Ok(Value::unnamed_composite(self.values)),
242        }
243    }
244}
245
246impl SerializeSeq for UnnamedCompositeSerializer {
247    type Ok = Value<()>;
248    type Error = SerializerError;
249
250    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
251    where
252        T: serde::Serialize + ?Sized,
253    {
254        self.serialize_element(value)
255    }
256
257    fn end(self) -> Result<Self::Ok, Self::Error> {
258        self.end()
259    }
260}
261
262impl SerializeTuple for UnnamedCompositeSerializer {
263    type Ok = Value<()>;
264    type Error = SerializerError;
265
266    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
267    where
268        T: serde::Serialize + ?Sized,
269    {
270        self.serialize_element(value)
271    }
272
273    fn end(self) -> Result<Self::Ok, Self::Error> {
274        self.end()
275    }
276}
277
278impl SerializeTupleStruct for UnnamedCompositeSerializer {
279    type Ok = Value<()>;
280    type Error = SerializerError;
281
282    fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
283    where
284        T: serde::Serialize + ?Sized,
285    {
286        self.serialize_element(value)
287    }
288
289    fn end(self) -> Result<Self::Ok, Self::Error> {
290        self.end()
291    }
292}
293
294impl SerializeTupleVariant for UnnamedCompositeSerializer {
295    type Ok = Value<()>;
296    type Error = SerializerError;
297
298    fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
299    where
300        T: serde::Serialize + ?Sized,
301    {
302        self.serialize_element(value)
303    }
304
305    fn end(self) -> Result<Self::Ok, Self::Error> {
306        self.end()
307    }
308}
309
310// Serializes things into named composite types.
311pub struct NamedCompositeSerializer {
312    // Only present if the thing should be a variant:
313    variant_name: Option<String>,
314    values: Vec<(String, Value<()>)>,
315    key: Option<String>,
316}
317
318impl NamedCompositeSerializer {
319    fn new_composite() -> Self {
320        NamedCompositeSerializer { variant_name: None, values: Vec::new(), key: None }
321    }
322
323    fn new_variant(variant_name: String) -> Self {
324        NamedCompositeSerializer { variant_name: Some(variant_name), values: Vec::new(), key: None }
325    }
326
327    fn serialize_field<T>(&mut self, key: &str, value: &T) -> Result<(), SerializerError>
328    where
329        T: serde::Serialize + ?Sized,
330    {
331        let key = key.to_string();
332        let inner = value.serialize(ValueSerializer)?;
333        self.values.push((key, inner));
334        Ok(())
335    }
336
337    fn end(self) -> Result<Value<()>, SerializerError> {
338        match self.variant_name {
339            Some(name) => Ok(Value::variant(name, Composite::Named(self.values))),
340            None => Ok(Value::named_composite(self.values)),
341        }
342    }
343}
344
345impl SerializeMap for NamedCompositeSerializer {
346    type Ok = Value<()>;
347    type Error = SerializerError;
348
349    fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
350    where
351        T: serde::Serialize + ?Sized,
352    {
353        let inner = key.serialize(ValueSerializer)?;
354        // Map keys must be stringish, because named composite values are strings
355        // and will be matched with the corresponding field names on struct types
356        // to SCALE encode/decode.
357        let key = match inner.value {
358            ValueDef::Primitive(Primitive::String(s)) => s,
359            ValueDef::Primitive(Primitive::Char(c)) => c.to_string(),
360            _ => return Err(SerializerError::MapKeyMustBeStringlike),
361        };
362        self.key = Some(key);
363        Ok(())
364    }
365
366    fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
367    where
368        T: serde::Serialize + ?Sized,
369    {
370        let key = self.key.take().expect("serialize_key must be called prior to serialize_value");
371        self.serialize_field(&key, value)
372    }
373
374    fn end(self) -> Result<Self::Ok, Self::Error> {
375        self.end()
376    }
377}
378
379impl SerializeStruct for NamedCompositeSerializer {
380    type Ok = Value<()>;
381    type Error = SerializerError;
382
383    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
384    where
385        T: serde::Serialize + ?Sized,
386    {
387        self.serialize_field(key, value)
388    }
389
390    fn end(self) -> Result<Self::Ok, Self::Error> {
391        self.end()
392    }
393}
394
395impl SerializeStructVariant for NamedCompositeSerializer {
396    type Ok = Value<()>;
397    type Error = SerializerError;
398
399    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
400    where
401        T: serde::Serialize + ?Sized,
402    {
403        self.serialize_field(key, value)
404    }
405
406    fn end(self) -> Result<Self::Ok, Self::Error> {
407        self.end()
408    }
409}
410
411#[cfg(test)]
412mod test {
413    use super::*;
414    use crate::{value, Value};
415    use core::fmt::Debug;
416    use serde::{Deserialize, Serialize};
417
418    // Make sure that things can serialize and deserialize back losslessly.
419    fn assert_ser_de<T: Serialize + Deserialize<'static> + Debug + PartialEq>(val: T) {
420        let actual = val.serialize(ValueSerializer).expect("can serialize");
421        let actual = T::deserialize(actual).expect("can deserialize again");
422        assert_eq!(val, actual, "value did not come deserialize back to the same");
423    }
424
425    // Make sure that things can serialize and deserialize back losslessly and to the expected Value.
426    fn assert_ser_de_eq<T: Serialize + Deserialize<'static> + Debug + PartialEq>(
427        val: T,
428        value: Value<()>,
429    ) {
430        // serialize and compare:
431        let actual = val.serialize(ValueSerializer).expect("can serialize");
432        assert_eq!(value, actual, "serializing mismatch");
433        // deserialize back and check we get the same thing back out:
434        let actual = T::deserialize(actual).expect("can deserialize again");
435        assert_eq!(val, actual, "deserialing mismatch");
436    }
437
438    #[test]
439    fn ser_de_primitives() {
440        assert_ser_de_eq(123u8, Value::u128(123));
441        assert_ser_de_eq(123u16, Value::u128(123));
442        assert_ser_de_eq(123u32, Value::u128(123));
443        assert_ser_de_eq(123u64, Value::u128(123));
444        assert_ser_de_eq(123u128, Value::u128(123));
445
446        assert_ser_de_eq(123i8, Value::i128(123));
447        assert_ser_de_eq(123i16, Value::i128(123));
448        assert_ser_de_eq(123i32, Value::i128(123));
449        assert_ser_de_eq(123i64, Value::i128(123));
450        assert_ser_de_eq(123i128, Value::i128(123));
451
452        assert_ser_de_eq(true, Value::bool(true));
453        assert_ser_de_eq(false, Value::bool(false));
454
455        assert_ser_de_eq("hello".to_string(), Value::string("hello"));
456        assert_ser_de_eq('a', Value::char('a'));
457    }
458
459    #[test]
460    fn ser_de_optionals() {
461        assert_ser_de_eq(Some(123u8), value!(Some(123u8)));
462        assert_ser_de_eq(None as Option<u8>, value!(None()));
463    }
464
465    #[test]
466    fn ser_de_unit_struct() {
467        #[derive(Deserialize, Serialize, Debug, PartialEq)]
468        struct Foo;
469
470        assert_ser_de_eq(Foo, value!(()));
471    }
472
473    #[test]
474    fn ser_de_named_struct() {
475        #[derive(Deserialize, Serialize, Debug, PartialEq)]
476        struct Foo {
477            a: u8,
478            b: bool,
479        }
480
481        let val = value!({a: 123u8, b: true});
482        assert_ser_de_eq(Foo { a: 123, b: true }, val);
483    }
484
485    #[test]
486    fn ser_de_tuple_struct() {
487        #[derive(Deserialize, Serialize, Debug, PartialEq)]
488        struct Foo(u8, bool);
489
490        let val = value!((123u8, true));
491        assert_ser_de_eq(Foo(123, true), val);
492    }
493
494    #[test]
495    fn ser_de_sequences() {
496        assert_ser_de_eq(vec![1, 2, 3, 4, 5u8], value!((1u8, 2u8, 3u8, 4u8, 5u8)));
497        assert_ser_de_eq([1, 2, 3, 4, 5u8], value!((1u8, 2u8, 3u8, 4u8, 5u8)));
498
499        assert_ser_de_eq((1u8, true, 'a', "hello".to_string()), value!((1u8, true, 'a', "hello")));
500    }
501
502    #[test]
503    fn ser_de_variants() {
504        #[derive(Debug, PartialEq, Serialize, Deserialize)]
505        enum Foo {
506            A(bool, u8),
507            B,
508            C { hello: String, value: i64 },
509        }
510
511        assert_ser_de_eq(Foo::A(true, 123), value!(A(true, 123u8)));
512        assert_ser_de_eq(Foo::B, value!(B()));
513        assert_ser_de_eq(
514            Foo::C { hello: "World".to_string(), value: 123 },
515            value!(C { hello: "World", value: 123 }),
516        );
517    }
518
519    #[test]
520    fn ser_de_maps() {
521        use alloc::collections::BTreeMap;
522
523        let m = {
524            let mut m = BTreeMap::new();
525            m.insert("a".to_string(), 1u8);
526            m.insert("b".to_string(), 2u8);
527            m.insert("c".to_string(), 3u8);
528            m
529        };
530        assert_ser_de(m);
531
532        // chars as keys are fine, too:
533        let m = {
534            let mut m = BTreeMap::new();
535            m.insert('a', 1u8);
536            m.insert('b', 2u8);
537            m.insert('c', 3u8);
538            m
539        };
540        assert_ser_de(m);
541    }
542}