Skip to main content

zen_types/rcvalue/
conv.rs

1use crate::rcvalue::RcValue;
2use crate::variable::{ToVariable, Variable};
3use rust_decimal::Decimal;
4#[cfg(not(feature = "arbitrary_precision"))]
5use rust_decimal::prelude::FromPrimitive;
6use serde_json::Value;
7use std::rc::Rc;
8
9impl ToVariable for RcValue {
10    fn to_variable(&self) -> Variable {
11        match self {
12            RcValue::Null => Variable::Null,
13            RcValue::Bool(b) => Variable::Bool(*b),
14            RcValue::Number(n) => Variable::Number(*n),
15            RcValue::String(s) => Variable::String(Rc::from(s.as_ref())),
16            RcValue::Array(arr) => {
17                Variable::from_array(arr.iter().map(|v| v.to_variable()).collect())
18            }
19            RcValue::Object(obj) => Variable::from_object(
20                obj.iter()
21                    .map(|(k, v)| (Rc::from(k.as_ref()), v.to_variable()))
22                    .collect(),
23            ),
24        }
25    }
26}
27
28impl From<&Variable> for RcValue {
29    fn from(value: &Variable) -> Self {
30        match value {
31            Variable::Null => RcValue::Null,
32            Variable::Bool(b) => RcValue::Bool(*b),
33            Variable::Number(n) => RcValue::Number(*n),
34            Variable::String(s) => RcValue::String(s.clone()),
35            Variable::Array(arr) => {
36                let arr = arr.borrow();
37                RcValue::Array(arr.iter().map(RcValue::from).collect())
38            }
39            Variable::Object(obj) => {
40                let obj = obj.borrow();
41                RcValue::Object(
42                    obj.iter()
43                        .map(|(k, v)| (k.clone(), RcValue::from(v)))
44                        .collect(),
45                )
46            }
47            Variable::Dynamic(d) => RcValue::from(&d.to_value()),
48        }
49    }
50}
51
52impl From<Variable> for RcValue {
53    fn from(value: Variable) -> Self {
54        Self::from(&value)
55    }
56}
57
58impl From<&Value> for RcValue {
59    fn from(value: &Value) -> Self {
60        match value {
61            Value::Null => RcValue::Null,
62            Value::Bool(b) => RcValue::Bool(*b),
63            Value::Number(n) => {
64                #[cfg(feature = "arbitrary_precision")]
65                {
66                    RcValue::Number(
67                        Decimal::from_str_exact(n.as_str())
68                            .or_else(|_| Decimal::from_scientific(n.as_str()))
69                            .expect("Allowed number"),
70                    )
71                }
72
73                #[cfg(not(feature = "arbitrary_precision"))]
74                {
75                    if let Some(u) = n.as_u64() {
76                        return RcValue::Number(Decimal::from(u));
77                    }
78
79                    if let Some(i) = n.as_i64() {
80                        return RcValue::Number(Decimal::from(i));
81                    }
82
83                    if let Some(f) = n.as_f64() {
84                        return RcValue::Number(Decimal::from_f64(f).expect("Allowed number"));
85                    }
86
87                    unreachable!(
88                        "serde_json::Number is always u64, i64, or f64 without arbitrary_precision"
89                    );
90                }
91            }
92            Value::String(s) => RcValue::String(Rc::from(s.as_str())),
93            Value::Array(arr) => RcValue::Array(arr.iter().map(RcValue::from).collect()),
94            Value::Object(obj) => RcValue::Object(
95                obj.iter()
96                    .map(|(k, v)| (Rc::from(k.as_str()), RcValue::from(v)))
97                    .collect(),
98            ),
99        }
100    }
101}