ciborium/value/
ser.rs

1// SPDX-License-Identifier: Apache-2.0
2
3use super::{Error, Value};
4
5use alloc::{vec, vec::Vec};
6
7use ::serde::ser::{self, SerializeMap as _, SerializeSeq as _, SerializeTupleVariant as _};
8
9impl ser::Serialize for Value {
10    #[inline]
11    fn serialize<S: ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
12        match self {
13            Value::Bytes(x) => serializer.serialize_bytes(x),
14            Value::Bool(x) => serializer.serialize_bool(*x),
15            Value::Text(x) => serializer.serialize_str(x),
16            Value::Null => serializer.serialize_unit(),
17
18            Value::Tag(t, v) => {
19                let mut acc = serializer.serialize_tuple_variant("@@TAG@@", 0, "@@TAGGED@@", 2)?;
20                acc.serialize_field(t)?;
21                acc.serialize_field(v)?;
22                acc.end()
23            }
24
25            Value::Float(x) => {
26                let y = *x as f32;
27                if (y as f64).to_bits() == x.to_bits() {
28                    serializer.serialize_f32(y)
29                } else {
30                    serializer.serialize_f64(*x)
31                }
32            }
33
34            Value::Integer(x) => {
35                if let Ok(x) = u8::try_from(*x) {
36                    serializer.serialize_u8(x)
37                } else if let Ok(x) = i8::try_from(*x) {
38                    serializer.serialize_i8(x)
39                } else if let Ok(x) = u16::try_from(*x) {
40                    serializer.serialize_u16(x)
41                } else if let Ok(x) = i16::try_from(*x) {
42                    serializer.serialize_i16(x)
43                } else if let Ok(x) = u32::try_from(*x) {
44                    serializer.serialize_u32(x)
45                } else if let Ok(x) = i32::try_from(*x) {
46                    serializer.serialize_i32(x)
47                } else if let Ok(x) = u64::try_from(*x) {
48                    serializer.serialize_u64(x)
49                } else if let Ok(x) = i64::try_from(*x) {
50                    serializer.serialize_i64(x)
51                } else if let Ok(x) = u128::try_from(*x) {
52                    serializer.serialize_u128(x)
53                } else if let Ok(x) = i128::try_from(*x) {
54                    serializer.serialize_i128(x)
55                } else {
56                    unreachable!()
57                }
58            }
59
60            Value::Array(x) => {
61                let mut map = serializer.serialize_seq(Some(x.len()))?;
62
63                for v in x {
64                    map.serialize_element(v)?;
65                }
66
67                map.end()
68            }
69
70            Value::Map(x) => {
71                let mut map = serializer.serialize_map(Some(x.len()))?;
72
73                for (k, v) in x {
74                    map.serialize_entry(k, v)?;
75                }
76
77                map.end()
78            }
79        }
80    }
81}
82
83macro_rules! mkserialize {
84    ($($f:ident($v:ty)),+ $(,)?) => {
85        $(
86            #[inline]
87            fn $f(self, v: $v) -> Result<Self::Ok, Self::Error> {
88                Ok(v.into())
89            }
90        )+
91    };
92}
93
94struct Tagged {
95    tag: Option<u64>,
96    val: Option<Value>,
97}
98
99struct Named<T> {
100    name: &'static str,
101    data: T,
102    tag: Option<Tagged>,
103}
104
105struct Map {
106    data: Vec<(Value, Value)>,
107    temp: Option<Value>,
108}
109
110struct Serializer<T>(T);
111
112impl ser::Serializer for Serializer<()> {
113    type Ok = Value;
114    type Error = Error;
115
116    type SerializeSeq = Serializer<Vec<Value>>;
117    type SerializeTuple = Serializer<Vec<Value>>;
118    type SerializeTupleStruct = Serializer<Vec<Value>>;
119    type SerializeTupleVariant = Serializer<Named<Vec<Value>>>;
120    type SerializeMap = Serializer<Map>;
121    type SerializeStruct = Serializer<Vec<(Value, Value)>>;
122    type SerializeStructVariant = Serializer<Named<Vec<(Value, Value)>>>;
123
124    mkserialize! {
125        serialize_bool(bool),
126
127        serialize_f32(f32),
128        serialize_f64(f64),
129
130        serialize_i8(i8),
131        serialize_i16(i16),
132        serialize_i32(i32),
133        serialize_i64(i64),
134        serialize_i128(i128),
135        serialize_u8(u8),
136        serialize_u16(u16),
137        serialize_u32(u32),
138        serialize_u64(u64),
139        serialize_u128(u128),
140
141        serialize_char(char),
142        serialize_str(&str),
143        serialize_bytes(&[u8]),
144    }
145
146    #[inline]
147    fn serialize_none(self) -> Result<Value, Error> {
148        Ok(Value::Null)
149    }
150
151    #[inline]
152    fn serialize_some<U: ?Sized + ser::Serialize>(self, value: &U) -> Result<Value, Error> {
153        value.serialize(self)
154    }
155
156    #[inline]
157    fn serialize_unit(self) -> Result<Value, Error> {
158        self.serialize_none()
159    }
160
161    #[inline]
162    fn serialize_unit_struct(self, _name: &'static str) -> Result<Value, Error> {
163        self.serialize_unit()
164    }
165
166    #[inline]
167    fn serialize_unit_variant(
168        self,
169        _name: &'static str,
170        _index: u32,
171        variant: &'static str,
172    ) -> Result<Value, Error> {
173        Ok(variant.into())
174    }
175
176    #[inline]
177    fn serialize_newtype_struct<U: ?Sized + ser::Serialize>(
178        self,
179        _name: &'static str,
180        value: &U,
181    ) -> Result<Value, Error> {
182        value.serialize(self)
183    }
184
185    #[inline]
186    fn serialize_newtype_variant<U: ?Sized + ser::Serialize>(
187        self,
188        name: &'static str,
189        _index: u32,
190        variant: &'static str,
191        value: &U,
192    ) -> Result<Value, Error> {
193        Ok(match (name, variant) {
194            ("@@TAG@@", "@@UNTAGGED@@") => Value::serialized(value)?,
195            _ => vec![(variant.into(), Value::serialized(value)?)].into(),
196        })
197    }
198
199    #[inline]
200    fn serialize_seq(self, length: Option<usize>) -> Result<Self::SerializeSeq, Error> {
201        Ok(Serializer(Vec::with_capacity(length.unwrap_or(0))))
202    }
203
204    #[inline]
205    fn serialize_tuple(self, length: usize) -> Result<Self::SerializeTuple, Error> {
206        self.serialize_seq(Some(length))
207    }
208
209    #[inline]
210    fn serialize_tuple_struct(
211        self,
212        _name: &'static str,
213        length: usize,
214    ) -> Result<Self::SerializeTupleStruct, Error> {
215        self.serialize_seq(Some(length))
216    }
217
218    #[inline]
219    fn serialize_tuple_variant(
220        self,
221        name: &'static str,
222        _index: u32,
223        variant: &'static str,
224        length: usize,
225    ) -> Result<Self::SerializeTupleVariant, Error> {
226        Ok(Serializer(Named {
227            name: variant,
228            data: Vec::with_capacity(length),
229            tag: match (name, variant) {
230                ("@@TAG@@", "@@TAGGED@@") => Some(Tagged {
231                    tag: None,
232                    val: None,
233                }),
234
235                _ => None,
236            },
237        }))
238    }
239
240    #[inline]
241    fn serialize_map(self, length: Option<usize>) -> Result<Self::SerializeMap, Error> {
242        Ok(Serializer(Map {
243            data: Vec::with_capacity(length.unwrap_or(0)),
244            temp: None,
245        }))
246    }
247
248    #[inline]
249    fn serialize_struct(
250        self,
251        _name: &'static str,
252        length: usize,
253    ) -> Result<Self::SerializeStruct, Error> {
254        Ok(Serializer(Vec::with_capacity(length)))
255    }
256
257    #[inline]
258    fn serialize_struct_variant(
259        self,
260        _name: &'static str,
261        _index: u32,
262        variant: &'static str,
263        length: usize,
264    ) -> Result<Self::SerializeStructVariant, Error> {
265        Ok(Serializer(Named {
266            name: variant,
267            data: Vec::with_capacity(length),
268            tag: None,
269        }))
270    }
271
272    fn is_human_readable(&self) -> bool {
273        false
274    }
275}
276
277impl ser::SerializeSeq for Serializer<Vec<Value>> {
278    type Ok = Value;
279    type Error = Error;
280
281    #[inline]
282    fn serialize_element<U: ?Sized + ser::Serialize>(&mut self, value: &U) -> Result<(), Error> {
283        self.0.push(Value::serialized(&value)?);
284        Ok(())
285    }
286
287    #[inline]
288    fn end(self) -> Result<Self::Ok, Self::Error> {
289        Ok(self.0.into())
290    }
291}
292
293impl ser::SerializeTuple for Serializer<Vec<Value>> {
294    type Ok = Value;
295    type Error = Error;
296
297    #[inline]
298    fn serialize_element<U: ?Sized + ser::Serialize>(&mut self, value: &U) -> Result<(), Error> {
299        self.0.push(Value::serialized(&value)?);
300        Ok(())
301    }
302
303    #[inline]
304    fn end(self) -> Result<Self::Ok, Self::Error> {
305        Ok(self.0.into())
306    }
307}
308
309impl ser::SerializeTupleStruct for Serializer<Vec<Value>> {
310    type Ok = Value;
311    type Error = Error;
312
313    #[inline]
314    fn serialize_field<U: ?Sized + ser::Serialize>(&mut self, value: &U) -> Result<(), Error> {
315        self.0.push(Value::serialized(&value)?);
316        Ok(())
317    }
318
319    #[inline]
320    fn end(self) -> Result<Self::Ok, Self::Error> {
321        Ok(self.0.into())
322    }
323}
324
325impl ser::SerializeTupleVariant for Serializer<Named<Vec<Value>>> {
326    type Ok = Value;
327    type Error = Error;
328
329    #[inline]
330    fn serialize_field<U: ?Sized + ser::Serialize>(&mut self, value: &U) -> Result<(), Error> {
331        match self.0.tag.as_mut() {
332            Some(tag) => match tag.tag {
333                None => match value.serialize(crate::tag::Serializer) {
334                    Ok(t) => tag.tag = Some(t),
335                    Err(..) => return Err(ser::Error::custom("expected tag")),
336                },
337
338                Some(..) => tag.val = Some(Value::serialized(value)?),
339            },
340
341            None => self.0.data.push(Value::serialized(value)?),
342        }
343
344        Ok(())
345    }
346
347    #[inline]
348    fn end(self) -> Result<Self::Ok, Self::Error> {
349        Ok(match self.0.tag {
350            Some(tag) => match tag {
351                Tagged {
352                    tag: Some(t),
353                    val: Some(v),
354                } => Value::Tag(t, v.into()),
355                _ => return Err(ser::Error::custom("invalid tag input")),
356            },
357
358            None => vec![(self.0.name.into(), self.0.data.into())].into(),
359        })
360    }
361}
362
363impl ser::SerializeMap for Serializer<Map> {
364    type Ok = Value;
365    type Error = Error;
366
367    #[inline]
368    fn serialize_key<U: ?Sized + ser::Serialize>(&mut self, key: &U) -> Result<(), Error> {
369        self.0.temp = Some(Value::serialized(key)?);
370        Ok(())
371    }
372
373    #[inline]
374    fn serialize_value<U: ?Sized + ser::Serialize>(&mut self, value: &U) -> Result<(), Error> {
375        let key = self.0.temp.take().unwrap();
376        let val = Value::serialized(&value)?;
377
378        self.0.data.push((key, val));
379        Ok(())
380    }
381
382    #[inline]
383    fn end(self) -> Result<Self::Ok, Self::Error> {
384        Ok(self.0.data.into())
385    }
386}
387
388impl ser::SerializeStruct for Serializer<Vec<(Value, Value)>> {
389    type Ok = Value;
390    type Error = Error;
391
392    #[inline]
393    fn serialize_field<U: ?Sized + ser::Serialize>(
394        &mut self,
395        key: &'static str,
396        value: &U,
397    ) -> Result<(), Error> {
398        let k = Value::serialized(&key)?;
399        let v = Value::serialized(&value)?;
400        self.0.push((k, v));
401        Ok(())
402    }
403
404    #[inline]
405    fn end(self) -> Result<Self::Ok, Self::Error> {
406        Ok(self.0.into())
407    }
408}
409
410impl ser::SerializeStructVariant for Serializer<Named<Vec<(Value, Value)>>> {
411    type Ok = Value;
412    type Error = Error;
413
414    #[inline]
415    fn serialize_field<U: ?Sized + ser::Serialize>(
416        &mut self,
417        key: &'static str,
418        value: &U,
419    ) -> Result<(), Self::Error> {
420        let k = Value::serialized(&key)?;
421        let v = Value::serialized(&value)?;
422        self.0.data.push((k, v));
423        Ok(())
424    }
425
426    #[inline]
427    fn end(self) -> Result<Self::Ok, Self::Error> {
428        Ok(vec![(self.0.name.into(), self.0.data.into())].into())
429    }
430}
431
432impl Value {
433    /// Serializes an object into a `Value`
434    #[inline]
435    pub fn serialized<T: ?Sized + ser::Serialize>(value: &T) -> Result<Self, Error> {
436        value.serialize(Serializer(()))
437    }
438}