zen_expression/variable/
de.rs

1use crate::variable::Variable;
2use ahash::{HashMap, HashMapExt};
3use rust_decimal::prelude::FromPrimitive;
4use rust_decimal::Decimal;
5use serde::de::{DeserializeSeed, Error, MapAccess, SeqAccess, Unexpected, Visitor};
6use serde::{Deserialize, Deserializer};
7use std::fmt::Formatter;
8use std::marker::PhantomData;
9use std::ops::Deref;
10use std::rc::Rc;
11
12struct VariableVisitor;
13
14pub(super) const NUMBER_TOKEN: &str = "$serde_json::private::Number";
15
16impl<'de> Visitor<'de> for VariableVisitor {
17    type Value = Variable;
18
19    fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
20        formatter.write_str("A valid type")
21    }
22
23    fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
24    where
25        E: Error,
26    {
27        Ok(Variable::Bool(v))
28    }
29
30    fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
31    where
32        E: Error,
33    {
34        Ok(Variable::Number(Decimal::from_i64(v).ok_or_else(|| {
35            Error::invalid_value(Unexpected::Signed(v), &self)
36        })?))
37    }
38
39    fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
40    where
41        E: Error,
42    {
43        Ok(Variable::Number(Decimal::from_u64(v).ok_or_else(|| {
44            Error::invalid_value(Unexpected::Unsigned(v), &self)
45        })?))
46    }
47
48    fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
49    where
50        E: Error,
51    {
52        Ok(Variable::Number(Decimal::from_f64(v).ok_or_else(|| {
53            Error::invalid_value(Unexpected::Float(v), &self)
54        })?))
55    }
56
57    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
58    where
59        E: Error,
60    {
61        Ok(Variable::String(Rc::from(v)))
62    }
63
64    fn visit_unit<E>(self) -> Result<Self::Value, E>
65    where
66        E: Error,
67    {
68        Ok(Variable::Null)
69    }
70
71    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
72    where
73        A: SeqAccess<'de>,
74    {
75        let mut vec = Vec::with_capacity(seq.size_hint().unwrap_or_default());
76        while let Some(value) = seq.next_element_seed(VariableDeserializer)? {
77            vec.push(value);
78        }
79
80        Ok(Variable::from_array(vec))
81    }
82
83    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
84    where
85        A: MapAccess<'de>,
86    {
87        let mut m = HashMap::with_capacity(map.size_hint().unwrap_or_default());
88        let mut first = true;
89
90        while let Some((key, value)) =
91            map.next_entry_seed(PhantomData::<Rc<str>>, VariableDeserializer)?
92        {
93            if first && key.deref() == NUMBER_TOKEN {
94                let str = value
95                    .as_str()
96                    .ok_or_else(|| Error::custom("failed to deserialize number"))?;
97
98                return Ok(Variable::Number(
99                    Decimal::from_str_exact(str)
100                        .or_else(|_| Decimal::from_scientific(str))
101                        .map_err(|_| Error::custom("invalid number"))?,
102                ));
103            }
104
105            m.insert(key, value);
106            first = false;
107        }
108
109        Ok(Variable::from_object(m))
110    }
111}
112
113pub struct VariableDeserializer;
114
115impl<'de> DeserializeSeed<'de> for VariableDeserializer {
116    type Value = Variable;
117
118    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
119    where
120        D: Deserializer<'de>,
121    {
122        deserializer.deserialize_any(VariableVisitor)
123    }
124}
125
126impl<'de> Deserialize<'de> for Variable {
127    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
128    where
129        D: Deserializer<'de>,
130    {
131        deserializer.deserialize_any(VariableVisitor)
132    }
133}