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