serde_lite/
deserialize.rs

1use std::{
2    borrow::Cow,
3    cell::{Cell, RefCell},
4    collections::HashMap,
5    convert::TryInto,
6    hash::Hash,
7    rc::Rc,
8    sync::{Arc, Mutex},
9};
10
11use crate::{Error, Intermediate};
12
13/// Deserialize trait.
14///
15/// The trait can be implemented by objects the can deserialized from the
16/// intermediate representation.
17pub trait Deserialize {
18    /// Deserialize an object instance.
19    fn deserialize(val: &Intermediate) -> Result<Self, Error>
20    where
21        Self: Sized;
22}
23
24impl Deserialize for bool {
25    #[inline]
26    fn deserialize(val: &Intermediate) -> Result<Self, Error> {
27        val.as_bool()
28            .ok_or_else(|| Error::invalid_value_static("bool"))
29    }
30}
31
32macro_rules! deserialize_for_signed_int {
33    ( $x:ty ) => {
34        impl Deserialize for $x {
35            #[inline]
36            fn deserialize(val: &Intermediate) -> Result<Self, Error> {
37                val.as_number()
38                    .ok_or_else(|| Error::invalid_value_static("integer"))
39                    .and_then(|n| n.try_into())
40            }
41        }
42    };
43}
44
45macro_rules! deserialize_for_unsigned_int {
46    ( $x:ty ) => {
47        impl Deserialize for $x {
48            #[inline]
49            fn deserialize(val: &Intermediate) -> Result<Self, Error> {
50                val.as_number()
51                    .ok_or_else(|| Error::invalid_value_static("unsigned integer"))
52                    .and_then(|n| n.try_into())
53            }
54        }
55    };
56}
57
58deserialize_for_signed_int!(i8);
59deserialize_for_signed_int!(i16);
60deserialize_for_signed_int!(i32);
61deserialize_for_signed_int!(i64);
62deserialize_for_signed_int!(isize);
63
64deserialize_for_unsigned_int!(u8);
65deserialize_for_unsigned_int!(u16);
66deserialize_for_unsigned_int!(u32);
67deserialize_for_unsigned_int!(u64);
68deserialize_for_unsigned_int!(usize);
69
70impl Deserialize for i128 {
71    #[inline]
72    fn deserialize(val: &Intermediate) -> Result<Self, Error> {
73        i64::deserialize(val).map(|v| v.into())
74    }
75}
76
77impl Deserialize for u128 {
78    #[inline]
79    fn deserialize(val: &Intermediate) -> Result<Self, Error> {
80        u64::deserialize(val).map(|v| v.into())
81    }
82}
83
84impl Deserialize for f32 {
85    #[inline]
86    fn deserialize(val: &Intermediate) -> Result<Self, Error> {
87        f64::deserialize(val).map(|v| v as _)
88    }
89}
90
91impl Deserialize for f64 {
92    #[inline]
93    fn deserialize(val: &Intermediate) -> Result<Self, Error> {
94        val.as_number()
95            .map(|n| n.into())
96            .ok_or_else(|| Error::invalid_value_static("number"))
97    }
98}
99
100impl Deserialize for char {
101    #[inline]
102    fn deserialize(val: &Intermediate) -> Result<Self, Error> {
103        val.as_char()
104            .ok_or_else(|| Error::invalid_value_static("character"))
105    }
106}
107
108impl Deserialize for String {
109    #[inline]
110    fn deserialize(val: &Intermediate) -> Result<Self, Error> {
111        val.as_str()
112            .map(String::from)
113            .ok_or_else(|| Error::invalid_value_static("string"))
114    }
115}
116
117impl<T> Deserialize for Option<T>
118where
119    T: Deserialize,
120{
121    #[inline]
122    fn deserialize(val: &Intermediate) -> Result<Self, Error>
123    where
124        Self: Sized,
125    {
126        if val.is_none() {
127            Ok(None)
128        } else {
129            T::deserialize(val).map(Some)
130        }
131    }
132}
133
134impl<T> Deserialize for Vec<T>
135where
136    T: Deserialize,
137{
138    fn deserialize(val: &Intermediate) -> Result<Self, Error>
139    where
140        Self: Sized,
141    {
142        if let Some(val) = val.as_array() {
143            let mut res = Vec::with_capacity(val.len());
144
145            for elem in val {
146                res.push(T::deserialize(elem)?);
147            }
148
149            Ok(res)
150        } else {
151            Err(Error::invalid_value_static("array"))
152        }
153    }
154}
155
156impl<T> Deserialize for [T; 0] {
157    #[inline]
158    fn deserialize(_: &Intermediate) -> Result<Self, Error>
159    where
160        Self: Sized,
161    {
162        Ok([])
163    }
164}
165
166macro_rules! deserialize_array {
167    ( $len:expr => ($($n:tt)+) ) => {
168        impl<T> Deserialize for [T; $len]
169        where
170            T: Deserialize,
171        {
172            fn deserialize(val: &Intermediate) -> Result<Self, Error> {
173                if let Some(val) = val.as_array() {
174                    if val.len() < $len {
175                        return Err(Error::invalid_value_static(concat!("an array of length ", $len)));
176                    }
177
178                    Ok([
179                        $(
180                            T::deserialize(&val[$n])?
181                        ),+
182                    ])
183                } else {
184                    Err(Error::invalid_value_static(concat!("an array of length ", $len)))
185                }
186            }
187        }
188    };
189}
190
191deserialize_array!(1 => (0));
192deserialize_array!(2 => (0 1));
193deserialize_array!(3 => (0 1 2));
194deserialize_array!(4 => (0 1 2 3));
195deserialize_array!(5 => (0 1 2 3 4));
196deserialize_array!(6 => (0 1 2 3 4 5));
197deserialize_array!(7 => (0 1 2 3 4 5 6));
198deserialize_array!(8 => (0 1 2 3 4 5 6 7));
199deserialize_array!(9 => (0 1 2 3 4 5 6 7 8));
200deserialize_array!(10 => (0 1 2 3 4 5 6 7 8 9));
201deserialize_array!(11 => (0 1 2 3 4 5 6 7 8 9 10));
202deserialize_array!(12 => (0 1 2 3 4 5 6 7 8 9 10 11));
203deserialize_array!(13 => (0 1 2 3 4 5 6 7 8 9 10 11 12));
204deserialize_array!(14 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13));
205deserialize_array!(15 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14));
206deserialize_array!(16 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15));
207deserialize_array!(17 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16));
208deserialize_array!(18 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17));
209deserialize_array!(19 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18));
210deserialize_array!(20 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19));
211deserialize_array!(21 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20));
212deserialize_array!(22 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21));
213deserialize_array!(23 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22));
214deserialize_array!(24 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23));
215deserialize_array!(25 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24));
216deserialize_array!(26 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25));
217deserialize_array!(27 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26));
218deserialize_array!(28 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27));
219deserialize_array!(29 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28));
220deserialize_array!(30 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29));
221deserialize_array!(31 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30));
222deserialize_array!(32 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31));
223
224impl Deserialize for () {
225    #[inline]
226    fn deserialize(_: &Intermediate) -> Result<Self, Error> {
227        Ok(())
228    }
229}
230
231macro_rules! deserialize_tuple {
232    ( $len:expr => ($($n:tt $ty:ident)+) ) => {
233        impl<$($ty),+> Deserialize for ($($ty,)+)
234        where
235            $($ty: Deserialize,)+
236        {
237            fn deserialize(val: &Intermediate) -> Result<Self, Error> {
238                if let Some(val) = val.as_array() {
239                    if val.len() < $len {
240                        return Err(Error::invalid_value_static(concat!("an array of length ", $len)));
241                    }
242
243                    Ok((
244                        $(
245                            $ty::deserialize(&val[$n])?,
246                        )+
247                    ))
248                } else {
249                    Err(Error::invalid_value_static(concat!("an array of length ", $len)))
250                }
251            }
252        }
253    };
254}
255
256deserialize_tuple!(1 => (0 T0));
257deserialize_tuple!(2 => (0 T0 1 T1));
258deserialize_tuple!(3 => (0 T0 1 T1 2 T2));
259deserialize_tuple!(4 => (0 T0 1 T1 2 T2 3 T3));
260deserialize_tuple!(5 => (0 T0 1 T1 2 T2 3 T3 4 T4));
261deserialize_tuple!(6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5));
262deserialize_tuple!(7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6));
263deserialize_tuple!(8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7));
264deserialize_tuple!(9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8));
265deserialize_tuple!(10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9));
266deserialize_tuple!(11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10));
267deserialize_tuple!(12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11));
268deserialize_tuple!(13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12));
269deserialize_tuple!(14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13));
270deserialize_tuple!(15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14));
271deserialize_tuple!(16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15));
272
273impl<K, V> Deserialize for HashMap<K, V>
274where
275    K: From<Cow<'static, str>> + Eq + Hash,
276    V: Deserialize,
277{
278    fn deserialize(val: &Intermediate) -> Result<Self, Error>
279    where
280        Self: Sized,
281    {
282        let val = val
283            .as_map()
284            .ok_or_else(|| Error::invalid_value_static("map"))?;
285
286        let mut res = HashMap::with_capacity(val.len());
287
288        for (name, value) in val {
289            let k = K::from(name.clone());
290            let v = V::deserialize(value)?;
291
292            res.insert(k, v);
293        }
294
295        Ok(res)
296    }
297}
298
299#[cfg(feature = "preserve-order")]
300impl<K, V> Deserialize for indexmap::IndexMap<K, V>
301where
302    K: From<Cow<'static, str>> + Eq + Hash,
303    V: Deserialize,
304{
305    fn deserialize(val: &Intermediate) -> Result<Self, Error>
306    where
307        Self: Sized,
308    {
309        let val = val
310            .as_map()
311            .ok_or_else(|| Error::invalid_value_static("map"))?;
312
313        let mut res = indexmap::IndexMap::with_capacity(val.len());
314
315        for (name, value) in val {
316            let k = K::from(name.clone());
317            let v = V::deserialize(value)?;
318
319            res.insert(k, v);
320        }
321
322        Ok(res)
323    }
324}
325
326macro_rules! deserialize_wrapper {
327    ( $x:ident ) => {
328        impl<T> Deserialize for $x<T>
329        where
330            T: Deserialize,
331        {
332            #[inline]
333            fn deserialize(val: &Intermediate) -> Result<Self, Error> {
334                let inner = T::deserialize(val)?;
335
336                Ok($x::new(inner))
337            }
338        }
339    };
340}
341
342deserialize_wrapper!(Box);
343deserialize_wrapper!(Rc);
344deserialize_wrapper!(Arc);
345deserialize_wrapper!(Cell);
346deserialize_wrapper!(RefCell);
347deserialize_wrapper!(Mutex);