serde_intermediate/value/
object.rs

1use crate::de::object::ObjectVisitor;
2use serde::{
3    ser::{SerializeMap, SerializeSeq, SerializeStructVariant, SerializeTupleVariant},
4    Deserialize, Deserializer, Serialize, Serializer,
5};
6
7#[derive(Debug, Clone, PartialEq, PartialOrd)]
8pub enum Number {
9    SignedInteger(i64),
10    UnsignedInteger(u64),
11    Float(f64),
12}
13
14impl Eq for Number {}
15
16impl Number {
17    pub fn as_signed_integer(&self) -> Option<i64> {
18        match self {
19            Self::SignedInteger(v) => Some(*v),
20            _ => None,
21        }
22    }
23
24    pub fn as_unsigned_integer(&self) -> Option<u64> {
25        match self {
26            Self::UnsignedInteger(v) => Some(*v),
27            _ => None,
28        }
29    }
30
31    pub fn as_float(&self) -> Option<f64> {
32        match self {
33            Self::Float(v) => Some(*v),
34            _ => None,
35        }
36    }
37}
38
39impl Serialize for Number {
40    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
41    where
42        S: Serializer,
43    {
44        match self {
45            Self::SignedInteger(v) => serializer.serialize_i64(*v),
46            Self::UnsignedInteger(v) => serializer.serialize_u64(*v),
47            Self::Float(v) => serializer.serialize_f64(*v),
48        }
49    }
50}
51
52macro_rules! impl_number_from {
53    ($type:ty => $variant:ident) => {
54        impl From<$type> for Number {
55            fn from(value: $type) -> Self {
56                Self::$variant(value as _)
57            }
58        }
59    };
60}
61
62impl_number_from!(i8 => SignedInteger);
63impl_number_from!(i16 => SignedInteger);
64impl_number_from!(i32 => SignedInteger);
65impl_number_from!(i64 => SignedInteger);
66impl_number_from!(u8 => UnsignedInteger);
67impl_number_from!(u16 => UnsignedInteger);
68impl_number_from!(u32 => UnsignedInteger);
69impl_number_from!(u64 => UnsignedInteger);
70impl_number_from!(f32 => Float);
71impl_number_from!(f64 => Float);
72
73#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd)]
74pub enum Variant {
75    #[default]
76    Unit,
77    Wrapper(Box<Object>),
78    Array(Vec<Object>),
79    Map(Vec<(String, Object)>),
80}
81
82impl Variant {
83    pub fn unit() -> Self {
84        Self::Unit
85    }
86
87    pub fn wrapper(value: impl Into<Object>) -> Self {
88        Self::Wrapper(Box::new(value.into()))
89    }
90
91    pub fn array() -> Self {
92        Self::Array(Default::default())
93    }
94
95    pub fn array_from<T: Into<Object>>(value: impl IntoIterator<Item = T>) -> Self {
96        Self::Array(value.into_iter().map(|item| item.into()).collect())
97    }
98
99    pub fn item(self, value: impl Into<Object>) -> Self {
100        match self {
101            Self::Array(mut result) => {
102                result.push(value.into());
103                Self::Array(result)
104            }
105            _ => self,
106        }
107    }
108
109    pub fn map() -> Self {
110        Self::Map(Default::default())
111    }
112
113    pub fn map_from<K: ToString, V: Into<Object>>(value: impl IntoIterator<Item = (K, V)>) -> Self {
114        Self::Map(
115            value
116                .into_iter()
117                .map(|(key, value)| (key.to_string(), value.into()))
118                .collect(),
119        )
120    }
121
122    pub fn property(self, key: impl ToString, value: impl Into<Object>) -> Self {
123        match self {
124            Self::Map(mut result) => {
125                let key = key.to_string();
126                let value = value.into();
127                if let Some((_, item)) = result.iter_mut().find(|(k, _)| k == &key) {
128                    *item = value;
129                } else {
130                    result.push((key, value));
131                }
132                Self::Map(result)
133            }
134            _ => self,
135        }
136    }
137
138    pub fn as_unit(&self) -> Option<()> {
139        match self {
140            Self::Unit => Some(()),
141            _ => None,
142        }
143    }
144
145    pub fn as_wrapper(&self) -> Option<&Object> {
146        match self {
147            Self::Wrapper(v) => Some(v),
148            _ => None,
149        }
150    }
151
152    pub fn as_array(&self) -> Option<&[Object]> {
153        match self {
154            Self::Array(v) => Some(v),
155            _ => None,
156        }
157    }
158
159    pub fn as_map(&self) -> Option<&[(String, Object)]> {
160        match self {
161            Self::Map(v) => Some(v),
162            _ => None,
163        }
164    }
165}
166
167#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd)]
168pub enum Object {
169    #[default]
170    Unit,
171    Bool(bool),
172    Number(Number),
173    String(String),
174    Wrapper(Box<Object>),
175    Array(Vec<Object>),
176    Map(Vec<(Object, Object)>),
177    Option(Option<Box<Object>>),
178    Variant {
179        name: String,
180        value: Box<Variant>,
181    },
182}
183
184impl Object {
185    pub fn unit() -> Self {
186        Self::Unit
187    }
188
189    pub fn bool(value: bool) -> Self {
190        Self::Bool(value)
191    }
192
193    pub fn number(value: impl Into<Number>) -> Self {
194        Self::Number(value.into())
195    }
196
197    pub fn string(value: impl ToString) -> Self {
198        Self::String(value.to_string())
199    }
200
201    pub fn wrapper(value: impl Into<Object>) -> Self {
202        Self::Wrapper(Box::new(value.into()))
203    }
204
205    pub fn array() -> Self {
206        Self::Array(Default::default())
207    }
208
209    pub fn array_from<T: Into<Object>>(value: impl IntoIterator<Item = T>) -> Self {
210        Self::Array(value.into_iter().map(|item| item.into()).collect())
211    }
212
213    pub fn item(self, value: impl Into<Object>) -> Self {
214        match self {
215            Self::Array(mut result) => {
216                result.push(value.into());
217                Self::Array(result)
218            }
219            _ => self,
220        }
221    }
222
223    pub fn map() -> Self {
224        Self::Map(Default::default())
225    }
226
227    pub fn map_from<K: Into<Object>, V: Into<Object>>(
228        value: impl IntoIterator<Item = (K, V)>,
229    ) -> Self {
230        Self::Map(
231            value
232                .into_iter()
233                .map(|(key, value)| (key.into(), value.into()))
234                .collect(),
235        )
236    }
237
238    pub fn property(self, key: impl Into<Object>, value: impl Into<Object>) -> Self {
239        match self {
240            Self::Map(mut result) => {
241                let key = key.into();
242                let value = value.into();
243                if let Some((_, item)) = result.iter_mut().find(|(k, _)| k == &key) {
244                    *item = value;
245                } else {
246                    result.push((key, value));
247                }
248                Self::Map(result)
249            }
250            _ => self,
251        }
252    }
253
254    pub fn option(value: Option<impl Into<Object>>) -> Self {
255        Self::Option(value.map(|value| Box::new(value.into())))
256    }
257
258    pub fn variant(name: impl ToString, value: Variant) -> Self {
259        Self::Variant {
260            name: name.to_string(),
261            value: Box::new(value),
262        }
263    }
264
265    pub fn as_unit(&self) -> Option<()> {
266        match self {
267            Self::Unit => Some(()),
268            _ => None,
269        }
270    }
271
272    pub fn as_bool(&self) -> Option<bool> {
273        match self {
274            Self::Bool(v) => Some(*v),
275            _ => None,
276        }
277    }
278
279    pub fn as_number(&self) -> Option<&Number> {
280        match self {
281            Self::Number(v) => Some(v),
282            _ => None,
283        }
284    }
285
286    pub fn as_str(&self) -> Option<&str> {
287        match self {
288            Self::String(v) => Some(v.as_str()),
289            _ => None,
290        }
291    }
292
293    pub fn as_string(&self) -> Option<String> {
294        match self {
295            Self::String(v) => Some(v.to_owned()),
296            _ => None,
297        }
298    }
299
300    pub fn as_wrapper(&self) -> Option<&Object> {
301        match self {
302            Self::Wrapper(v) => Some(v),
303            _ => None,
304        }
305    }
306
307    pub fn as_array(&self) -> Option<&[Object]> {
308        match self {
309            Self::Array(v) => Some(v),
310            _ => None,
311        }
312    }
313
314    pub fn as_map(&self) -> Option<&[(Object, Object)]> {
315        match self {
316            Self::Map(v) => Some(v),
317            _ => None,
318        }
319    }
320
321    pub fn as_option(&self) -> Option<&Object> {
322        match self {
323            Self::Option(v) => v.as_ref().map(|v| &**v),
324            _ => None,
325        }
326    }
327
328    pub fn as_variant(&self) -> Option<(&str, &Variant)> {
329        match self {
330            Self::Variant { name, value } => Some((name.as_str(), value)),
331            _ => None,
332        }
333    }
334}
335
336impl Serialize for Object {
337    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
338    where
339        S: Serializer,
340    {
341        match self {
342            Self::Unit => serializer.serialize_unit(),
343            Self::Bool(v) => serializer.serialize_bool(*v),
344            Self::Number(v) => v.serialize(serializer),
345            Self::String(v) => serializer.serialize_str(v),
346            Self::Wrapper(v) => v.serialize(serializer),
347            Self::Array(v) => {
348                let mut seq = serializer.serialize_seq(Some(v.len()))?;
349                for item in v {
350                    seq.serialize_element(item)?;
351                }
352                seq.end()
353            }
354            Self::Map(v) => {
355                let mut map = serializer.serialize_map(Some(v.len()))?;
356                for (k, v) in v {
357                    map.serialize_entry(k, v)?;
358                }
359                map.end()
360            }
361            Self::Option(v) => match v {
362                Some(v) => serializer.serialize_some(v),
363                None => serializer.serialize_none(),
364            },
365            Self::Variant { name, value } => match &**value {
366                Variant::Unit => serializer.serialize_unit_variant("Object", 0, unsafe {
367                    std::mem::transmute::<&str, &str>(name.as_str())
368                }),
369                Variant::Wrapper(v) => serializer.serialize_newtype_variant(
370                    "Object",
371                    0,
372                    unsafe { std::mem::transmute::<&str, &str>(name.as_str()) },
373                    v,
374                ),
375                Variant::Array(v) => {
376                    let mut tv = serializer.serialize_tuple_variant(
377                        "Object",
378                        0,
379                        unsafe { std::mem::transmute::<&str, &str>(name.as_str()) },
380                        v.len(),
381                    )?;
382                    for item in v {
383                        tv.serialize_field(item)?;
384                    }
385                    tv.end()
386                }
387                Variant::Map(v) => {
388                    let mut sv = serializer.serialize_struct_variant(
389                        "Object",
390                        0,
391                        unsafe { std::mem::transmute::<&str, &str>(name.as_str()) },
392                        v.len(),
393                    )?;
394                    for (k, v) in v {
395                        sv.serialize_field(
396                            unsafe { std::mem::transmute::<&str, &str>(k.as_str()) },
397                            v,
398                        )?;
399                    }
400                    sv.end()
401                }
402            },
403        }
404    }
405}
406
407impl<'de> Deserialize<'de> for Object {
408    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
409    where
410        D: Deserializer<'de>,
411    {
412        deserializer.deserialize_any(ObjectVisitor)
413    }
414}