serde_lite/
intermediate.rs

1use std::{
2    borrow::Cow,
3    collections::HashMap,
4    convert::{TryFrom, TryInto},
5    fmt::{self, Formatter},
6};
7
8use serde::{
9    de::{MapAccess, SeqAccess, Visitor},
10    ser::{SerializeMap, SerializeSeq},
11    Deserialize, Deserializer, Serialize, Serializer,
12};
13
14use crate::{Error, Map};
15
16/// Number.
17#[derive(Debug, Copy, Clone)]
18pub enum Number {
19    Float(f64),
20    SignedInt(i64),
21    UnsignedInt(u64),
22}
23
24impl From<Number> for f64 {
25    #[inline]
26    fn from(n: Number) -> Self {
27        match n {
28            Number::Float(v) => v,
29            Number::SignedInt(v) => v as _,
30            Number::UnsignedInt(v) => v as _,
31        }
32    }
33}
34
35macro_rules! try_int_from_number {
36    ( $x:ty ) => {
37        impl TryFrom<Number> for $x {
38            type Error = Error;
39
40            #[inline]
41            fn try_from(n: Number) -> Result<Self, Self::Error> {
42                let res = match n {
43                    Number::Float(_) => return Err(Error::UnsupportedConversion),
44                    Number::SignedInt(v) => v.try_into(),
45                    Number::UnsignedInt(v) => v.try_into(),
46                };
47
48                res.map_err(|_| Error::OutOfBounds)
49            }
50        }
51    };
52}
53
54try_int_from_number!(i8);
55try_int_from_number!(i16);
56try_int_from_number!(i32);
57try_int_from_number!(isize);
58
59impl TryFrom<Number> for i64 {
60    type Error = Error;
61
62    #[inline]
63    fn try_from(n: Number) -> Result<Self, Self::Error> {
64        match n {
65            Number::Float(_) => Err(Error::UnsupportedConversion),
66            Number::SignedInt(v) => Ok(v),
67            Number::UnsignedInt(v) => v.try_into().map_err(|_| Error::OutOfBounds),
68        }
69    }
70}
71
72try_int_from_number!(u8);
73try_int_from_number!(u16);
74try_int_from_number!(u32);
75try_int_from_number!(usize);
76
77impl TryFrom<Number> for u64 {
78    type Error = Error;
79
80    #[inline]
81    fn try_from(n: Number) -> Result<Self, Self::Error> {
82        match n {
83            Number::Float(_) => Err(Error::UnsupportedConversion),
84            Number::SignedInt(v) => v.try_into().map_err(|_| Error::OutOfBounds),
85            Number::UnsignedInt(v) => Ok(v),
86        }
87    }
88}
89
90impl Serialize for Number {
91    #[inline]
92    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
93    where
94        S: Serializer,
95    {
96        match *self {
97            Self::Float(v) => serializer.serialize_f64(v),
98            Self::SignedInt(v) => serializer.serialize_i64(v),
99            Self::UnsignedInt(v) => serializer.serialize_u64(v),
100        }
101    }
102}
103
104impl<'de> Deserialize<'de> for Number {
105    #[inline]
106    fn deserialize<D>(deserializer: D) -> Result<Number, D::Error>
107    where
108        D: Deserializer<'de>,
109    {
110        struct NumberVisitor;
111
112        impl<'a> Visitor<'a> for NumberVisitor {
113            type Value = Number;
114
115            #[inline]
116            fn expecting(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
117                f.write_str("a number")
118            }
119
120            #[inline]
121            fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E> {
122                Ok(Number::SignedInt(value))
123            }
124
125            #[inline]
126            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> {
127                Ok(Number::UnsignedInt(value))
128            }
129
130            #[inline]
131            fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E> {
132                Ok(Number::Float(value))
133            }
134        }
135
136        deserializer.deserialize_any(NumberVisitor)
137    }
138}
139
140/// Construct the intermediate value directly using JSON syntax.
141///
142/// # Example
143/// ```rust
144/// use serde_lite::intermediate;
145///
146/// let data = intermediate!({
147///     "field1": null,
148///     "field2": "foo",
149///     "field3": 33,
150///     "field4": 44.4,
151///     "field5": [1, 2, 3, 4, 5],
152///     "field6": {
153///         "inner_field": "Hello!",
154///     }
155/// });
156/// ```
157#[macro_export]
158macro_rules! intermediate {
159    ({ $($key:literal : $value:tt),* $(,)? }) => {
160        $crate::Intermediate::Map({
161            let mut map = $crate::Map::new();
162            $(
163                map.insert_with_static_key($key, intermediate!($value));
164            )*
165            map
166        })
167    };
168
169    ([ $($item:tt),* $(,)? ]) => {
170        $crate::Intermediate::Array({
171            let mut arr = Vec::new();
172            $(
173                arr.push(intermediate!($item));
174            )*
175            arr
176        })
177    };
178
179    (null) => {
180        $crate::Intermediate::None
181    };
182
183    ($value:expr) => {
184        $crate::Intermediate::from($value)
185    };
186}
187
188/// Intermediate data representation.
189///
190/// The format is similar to JSON. It can be serialized/deserialized using
191/// serde.
192#[derive(Debug, Clone)]
193pub enum Intermediate {
194    None,
195    Bool(bool),
196    Number(Number),
197    String(Cow<'static, str>),
198    Array(Vec<Intermediate>),
199    Map(Map),
200}
201
202impl Intermediate {
203    /// Check if the value is None.
204    #[inline]
205    pub fn is_none(&self) -> bool {
206        matches!(self, Self::None)
207    }
208
209    /// Get the value as a boolean (if possible).
210    #[inline]
211    pub fn as_bool(&self) -> Option<bool> {
212        if let Self::Bool(v) = self {
213            Some(*v)
214        } else {
215            None
216        }
217    }
218
219    /// Get the numeric value (if possible).
220    #[inline]
221    pub fn as_number(&self) -> Option<Number> {
222        if let Self::Number(v) = self {
223            Some(*v)
224        } else {
225            None
226        }
227    }
228
229    /// Get the value as a character (if possible).
230    #[inline]
231    pub fn as_char(&self) -> Option<char> {
232        if let Some(s) = self.as_str() {
233            let mut chars = s.chars();
234
235            let first = chars.next();
236            let second = chars.next();
237
238            if second.is_some() {
239                None
240            } else {
241                first
242            }
243        } else {
244            None
245        }
246    }
247
248    /// Get the value as a string (if possible).
249    #[inline]
250    pub fn as_str(&self) -> Option<&str> {
251        if let Self::String(v) = self {
252            Some(v)
253        } else {
254            None
255        }
256    }
257
258    /// Get the value as an array (if possible).
259    #[inline]
260    pub fn as_array(&self) -> Option<&[Intermediate]> {
261        if let Self::Array(v) = self {
262            Some(v)
263        } else {
264            None
265        }
266    }
267
268    /// Get the value as a map (if possible).
269    #[inline]
270    pub fn as_map(&self) -> Option<&Map> {
271        if let Self::Map(v) = self {
272            Some(v)
273        } else {
274            None
275        }
276    }
277}
278
279impl From<()> for Intermediate {
280    #[inline]
281    fn from(_: ()) -> Self {
282        Self::None
283    }
284}
285
286impl From<bool> for Intermediate {
287    #[inline]
288    fn from(v: bool) -> Self {
289        Self::Bool(v)
290    }
291}
292
293impl From<Number> for Intermediate {
294    #[inline]
295    fn from(v: Number) -> Self {
296        Self::Number(v)
297    }
298}
299
300impl From<i64> for Intermediate {
301    #[inline]
302    fn from(v: i64) -> Self {
303        Self::from(Number::SignedInt(v))
304    }
305}
306
307impl From<u64> for Intermediate {
308    #[inline]
309    fn from(v: u64) -> Self {
310        Self::from(Number::UnsignedInt(v))
311    }
312}
313
314impl From<f32> for Intermediate {
315    #[inline]
316    fn from(v: f32) -> Self {
317        Self::from(Number::Float(v as _))
318    }
319}
320
321impl From<f64> for Intermediate {
322    #[inline]
323    fn from(v: f64) -> Self {
324        Self::from(Number::Float(v))
325    }
326}
327
328macro_rules! intermediate_from_signed_int {
329    ( $ty:ty ) => {
330        impl From<$ty> for Intermediate {
331            #[inline]
332            fn from(v: $ty) -> Self {
333                Self::from(Number::SignedInt(v.into()))
334            }
335        }
336    };
337}
338
339intermediate_from_signed_int!(i8);
340intermediate_from_signed_int!(i16);
341intermediate_from_signed_int!(i32);
342
343macro_rules! intermediate_from_unsigned_int {
344    ( $ty:ty ) => {
345        impl From<$ty> for Intermediate {
346            #[inline]
347            fn from(v: $ty) -> Self {
348                Self::from(Number::UnsignedInt(v.into()))
349            }
350        }
351    };
352}
353
354intermediate_from_unsigned_int!(u8);
355intermediate_from_unsigned_int!(u16);
356intermediate_from_unsigned_int!(u32);
357
358impl From<String> for Intermediate {
359    #[inline]
360    fn from(v: String) -> Self {
361        Self::String(Cow::Owned(v))
362    }
363}
364
365impl From<&str> for Intermediate {
366    #[inline]
367    fn from(v: &str) -> Self {
368        Self::String(Cow::Owned(String::from(v)))
369    }
370}
371
372impl<T> From<Vec<T>> for Intermediate
373where
374    Intermediate: From<T>,
375{
376    fn from(v: Vec<T>) -> Self {
377        let mut res = Vec::with_capacity(v.len());
378
379        for elem in v {
380            res.push(elem.into());
381        }
382
383        Self::Array(res)
384    }
385}
386
387impl<K, V> From<HashMap<K, V>> for Intermediate
388where
389    K: Into<Cow<'static, str>>,
390    V: Into<Intermediate>,
391{
392    fn from(map: HashMap<K, V>) -> Self {
393        let mut res = Map::with_capacity(map.len());
394
395        for (k, v) in map {
396            res.insert(k.into(), v.into());
397        }
398
399        Self::Map(res)
400    }
401}
402
403#[cfg(feature = "preserve-order")]
404impl<K, V> From<indexmap::IndexMap<K, V>> for Intermediate
405where
406    K: Into<Cow<'static, str>>,
407    V: Into<Intermediate>,
408{
409    fn from(map: indexmap::IndexMap<K, V>) -> Self {
410        let mut res = Map::with_capacity(map.len());
411
412        for (k, v) in map {
413            res.insert(k.into(), v.into());
414        }
415
416        Self::Map(res)
417    }
418}
419
420impl crate::Serialize for Intermediate {
421    #[inline]
422    fn serialize(&self) -> Result<Intermediate, Error> {
423        Ok(self.clone())
424    }
425}
426
427impl crate::Deserialize for Intermediate {
428    #[inline]
429    fn deserialize(input: &Intermediate) -> Result<Self, Error> {
430        Ok(input.clone())
431    }
432}
433
434impl crate::Update for Intermediate {
435    #[inline]
436    fn update(&mut self, other: &Intermediate) -> Result<(), Error> {
437        match self {
438            Self::Array(arr) => {
439                if let Self::Array(_) = other {
440                    arr.update(other)?;
441                } else {
442                    *self = other.clone();
443                }
444            }
445            Self::Map(map) => {
446                if let Self::Map(_) = other {
447                    map.update(other)?;
448                } else {
449                    *self = other.clone();
450                }
451            }
452            _ => *self = other.clone(),
453        }
454
455        Ok(())
456    }
457}
458
459impl Serialize for Intermediate {
460    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
461    where
462        S: Serializer,
463    {
464        match self {
465            Self::None => serializer.serialize_none(),
466            Self::Bool(v) => serializer.serialize_bool(*v),
467            Self::Number(v) => v.serialize(serializer),
468            Self::String(v) => serializer.serialize_str(v),
469            Self::Array(v) => {
470                let mut seq = serializer.serialize_seq(Some(v.len()))?;
471                for e in v {
472                    seq.serialize_element(e)?;
473                }
474                seq.end()
475            }
476            Self::Map(v) => {
477                let mut map = serializer.serialize_map(Some(v.len()))?;
478                for (k, v) in v {
479                    map.serialize_entry(k, v)?;
480                }
481                map.end()
482            }
483        }
484    }
485}
486
487impl<'de> Deserialize<'de> for Intermediate {
488    #[inline]
489    fn deserialize<D>(deserializer: D) -> Result<Intermediate, D::Error>
490    where
491        D: Deserializer<'de>,
492    {
493        struct ValueVisitor;
494
495        impl<'a> Visitor<'a> for ValueVisitor {
496            type Value = Intermediate;
497
498            #[inline]
499            fn expecting(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
500                f.write_str("a value")
501            }
502
503            #[inline]
504            fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E> {
505                Ok(Intermediate::Bool(value))
506            }
507
508            #[inline]
509            fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E> {
510                Ok(Intermediate::Number(Number::SignedInt(value)))
511            }
512
513            #[inline]
514            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> {
515                Ok(Intermediate::Number(Number::UnsignedInt(value)))
516            }
517
518            #[inline]
519            fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E> {
520                Ok(Intermediate::Number(Number::Float(value)))
521            }
522
523            #[inline]
524            fn visit_char<E>(self, value: char) -> Result<Self::Value, E> {
525                Ok(Intermediate::String(Cow::Owned(value.to_string())))
526            }
527
528            #[inline]
529            fn visit_string<E>(self, value: String) -> Result<Self::Value, E> {
530                Ok(Intermediate::String(Cow::Owned(value)))
531            }
532
533            #[inline]
534            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> {
535                Ok(Intermediate::String(Cow::Owned(String::from(value))))
536            }
537
538            fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E> {
539                let mut res = Vec::with_capacity(value.len());
540
541                for b in value {
542                    res.push(Intermediate::Number(Number::UnsignedInt(*b as _)));
543                }
544
545                Ok(Intermediate::Array(res))
546            }
547
548            #[inline]
549            fn visit_none<E>(self) -> Result<Self::Value, E> {
550                Ok(Intermediate::None)
551            }
552
553            #[inline]
554            fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
555            where
556                D: Deserializer<'a>,
557            {
558                Intermediate::deserialize(deserializer)
559            }
560
561            #[inline]
562            fn visit_unit<E>(self) -> Result<Self::Value, E> {
563                Ok(Intermediate::None)
564            }
565
566            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
567            where
568                A: SeqAccess<'a>,
569            {
570                let mut res = Vec::new();
571
572                if let Some(size) = seq.size_hint() {
573                    res.reserve(size);
574                }
575
576                while let Some(elem) = seq.next_element()? {
577                    res.push(elem);
578                }
579
580                Ok(Intermediate::Array(res))
581            }
582
583            fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
584            where
585                A: MapAccess<'a>,
586            {
587                let mut res = Map::new();
588
589                if let Some(size) = map.size_hint() {
590                    res.reserve(size);
591                }
592
593                while let Some((k, v)) = map.next_entry()? {
594                    res.insert(Cow::Owned(k), v);
595                }
596
597                Ok(Intermediate::Map(res))
598            }
599        }
600
601        deserializer.deserialize_any(ValueVisitor)
602    }
603}