zen_types/variable/
conv.rs1use crate::variable::Variable;
2use rust_decimal::Decimal;
3#[cfg(not(feature = "arbitrary_precision"))]
4use rust_decimal::prelude::FromPrimitive;
5use serde_json::{Number, Value};
6use std::rc::Rc;
7#[cfg(not(feature = "arbitrary_precision"))]
8use std::str::FromStr;
9
10impl From<Value> for Variable {
11 fn from(value: Value) -> Self {
12 match value {
13 Value::Null => Variable::Null,
14 Value::Bool(b) => Variable::Bool(b),
15 Value::Number(n) => {
16 #[cfg(feature = "arbitrary_precision")]
17 {
18 Variable::Number(
19 Decimal::from_str_exact(n.as_str())
20 .or_else(|_| Decimal::from_scientific(n.as_str()))
21 .expect("Allowed number"),
22 )
23 }
24
25 #[cfg(not(feature = "arbitrary_precision"))]
26 {
27 if let Some(n) = n.as_u64() {
28 return Variable::Number(n.into());
29 }
30
31 if let Some(n) = n.as_i64() {
32 return Variable::Number(n.into());
33 }
34
35 if let Some(n) = n.as_f64() {
36 return Variable::Number(Decimal::from_f64(n).expect("Allowed number"));
37 }
38
39 unreachable!(
40 "serde_json::Number is always u64, i64, or f64 without arbitrary_precision"
41 )
42 }
43 }
44 Value::String(s) => Variable::String(Rc::from(s.as_str())),
45 Value::Array(arr) => {
46 Variable::from_array(arr.into_iter().map(Variable::from).collect())
47 }
48 Value::Object(obj) => Variable::from_object(
49 obj.into_iter()
50 .map(|(k, v)| (Rc::from(k.as_str()), Variable::from(v)))
51 .collect(),
52 ),
53 }
54 }
55}
56
57impl From<&Value> for Variable {
58 fn from(value: &Value) -> Self {
59 match value {
60 Value::Null => Variable::Null,
61 Value::Bool(b) => Variable::Bool(*b),
62 Value::Number(n) => {
63 #[cfg(feature = "arbitrary_precision")]
64 {
65 Variable::Number(
66 Decimal::from_str_exact(n.as_str())
67 .or_else(|_| Decimal::from_scientific(n.as_str()))
68 .expect("Allowed number"),
69 )
70 }
71
72 #[cfg(not(feature = "arbitrary_precision"))]
73 {
74 if let Some(u) = n.as_u64() {
75 return Variable::Number(u.into());
76 }
77
78 if let Some(i) = n.as_i64() {
79 return Variable::Number(i.into());
80 }
81
82 if let Some(f) = n.as_f64() {
83 return Variable::Number(Decimal::from_f64(f).expect("Allowed number"));
84 }
85
86 unreachable!(
87 "serde_json::Number is always u64, i64, or f64 without arbitrary_precision"
88 );
89 }
90 }
91 Value::String(s) => Variable::String(Rc::from(s.as_str())),
92 Value::Array(arr) => Variable::from_array(arr.iter().map(Variable::from).collect()),
93 Value::Object(obj) => Variable::from_object(
94 obj.iter()
95 .map(|(k, v)| (Rc::from(k.as_str()), Variable::from(v)))
96 .collect(),
97 ),
98 }
99 }
100}
101
102impl From<Variable> for Value {
103 fn from(value: Variable) -> Self {
104 match value {
105 Variable::Null => Value::Null,
106 Variable::Bool(b) => Value::Bool(b),
107 Variable::Number(n) => {
108 #[cfg(feature = "arbitrary_precision")]
109 {
110 Value::Number(Number::from_string_unchecked(n.normalize().to_string()))
111 }
112 #[cfg(not(feature = "arbitrary_precision"))]
113 {
114 Value::Number(
115 Number::from_str(n.normalize().to_string().as_str())
116 .expect("Allowed number"),
117 )
118 }
119 }
120 Variable::String(s) => Value::String(s.to_string()),
121 Variable::Array(arr) => {
122 let vec = Rc::try_unwrap(arr)
123 .map(|a| a.into_inner())
124 .unwrap_or_else(|s| {
125 let borrowed = s.borrow();
126 borrowed.clone()
127 });
128
129 Value::Array(vec.into_iter().map(Value::from).collect())
130 }
131 Variable::Object(obj) => {
132 let hmap = Rc::try_unwrap(obj)
133 .map(|a| a.into_inner())
134 .unwrap_or_else(|s| {
135 let borrowed = s.borrow();
136 borrowed.clone()
137 });
138
139 Value::Object(
140 hmap.into_iter()
141 .map(|(k, v)| (k.to_string(), Value::from(v)))
142 .collect(),
143 )
144 }
145 Variable::Dynamic(d) => d.to_value(),
146 }
147 }
148}