mf_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::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(
20 &self,
21 formatter: &mut Formatter,
22 ) -> std::fmt::Result {
23 formatter.write_str("A valid type")
24 }
25
26 fn visit_bool<E>(
27 self,
28 v: bool,
29 ) -> Result<Self::Value, E>
30 where
31 E: Error,
32 {
33 Ok(Variable::Bool(v))
34 }
35
36 fn visit_i64<E>(
37 self,
38 v: i64,
39 ) -> Result<Self::Value, E>
40 where
41 E: Error,
42 {
43 Ok(Variable::Number(Decimal::from_i64(v).ok_or_else(|| {
44 Error::invalid_value(Unexpected::Signed(v), &self)
45 })?))
46 }
47
48 fn visit_u64<E>(
49 self,
50 v: u64,
51 ) -> Result<Self::Value, E>
52 where
53 E: Error,
54 {
55 Ok(Variable::Number(Decimal::from_u64(v).ok_or_else(|| {
56 Error::invalid_value(Unexpected::Unsigned(v), &self)
57 })?))
58 }
59
60 fn visit_f64<E>(
61 self,
62 v: f64,
63 ) -> Result<Self::Value, E>
64 where
65 E: Error,
66 {
67 Ok(Variable::Number(Decimal::from_f64(v).ok_or_else(|| {
68 Error::invalid_value(Unexpected::Float(v), &self)
69 })?))
70 }
71
72 fn visit_str<E>(
73 self,
74 v: &str,
75 ) -> Result<Self::Value, E>
76 where
77 E: Error,
78 {
79 Ok(Variable::String(Rc::from(v)))
80 }
81
82 fn visit_unit<E>(self) -> Result<Self::Value, E>
83 where
84 E: Error,
85 {
86 Ok(Variable::Null)
87 }
88
89 fn visit_seq<A>(
90 self,
91 mut seq: A,
92 ) -> Result<Self::Value, A::Error>
93 where
94 A: SeqAccess<'de>,
95 {
96 let mut vec = Vec::with_capacity(seq.size_hint().unwrap_or_default());
97 while let Some(value) = seq.next_element_seed(VariableDeserializer)? {
98 vec.push(value);
99 }
100
101 Ok(Variable::from_array(vec))
102 }
103
104 fn visit_map<A>(
105 self,
106 mut map: A,
107 ) -> Result<Self::Value, A::Error>
108 where
109 A: MapAccess<'de>,
110 {
111 let mut m = HashMap::with_capacity(map.size_hint().unwrap_or_default());
112 let mut first = true;
113
114 while let Some((key, value)) =
115 map.next_entry_seed(PhantomData::<Rc<str>>, VariableDeserializer)?
116 {
117 if first && key.deref() == NUMBER_TOKEN {
118 let str = value.as_str().ok_or_else(|| {
119 Error::custom("failed to deserialize number")
120 })?;
121
122 return Ok(Variable::Number(
123 Decimal::from_str_exact(str)
124 .or_else(|_| Decimal::from_scientific(str))
125 .map_err(|_| Error::custom("invalid number"))?,
126 ));
127 }
128
129 m.insert(key, value);
130 first = false;
131 }
132
133 Ok(Variable::from_object(m))
134 }
135}
136
137pub struct VariableDeserializer;
138
139impl<'de> DeserializeSeed<'de> for VariableDeserializer {
140 type Value = Variable;
141
142 fn deserialize<D>(
143 self,
144 deserializer: D,
145 ) -> Result<Self::Value, D::Error>
146 where
147 D: Deserializer<'de>,
148 {
149 deserializer.deserialize_any(VariableVisitor)
150 }
151}
152
153impl<'de> Deserialize<'de> for Variable {
154 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
155 where
156 D: Deserializer<'de>,
157 {
158 deserializer.deserialize_any(VariableVisitor)
159 }
160}