zen_expression/variable/
conv.rs1use crate::variable::Variable;
2use crate::vm::helpers::date_time;
3use crate::vm::VMError;
4use chrono::NaiveDateTime;
5use rust_decimal::prelude::ToPrimitive;
6use rust_decimal::Decimal;
7use serde_json::{Number, Value};
8use std::rc::Rc;
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 Variable::Number(Decimal::from_str_exact(n.as_str()).expect("Allowed number"))
17 }
18 Value::String(s) => Variable::String(Rc::from(s.as_str())),
19 Value::Array(arr) => {
20 Variable::from_array(arr.into_iter().map(Variable::from).collect())
21 }
22 Value::Object(obj) => Variable::from_object(
23 obj.into_iter()
24 .map(|(k, v)| (k, Variable::from(v)))
25 .collect(),
26 ),
27 }
28 }
29}
30
31impl From<&Value> for Variable {
32 fn from(value: &Value) -> Self {
33 match value {
34 Value::Null => Variable::Null,
35 Value::Bool(b) => Variable::Bool(*b),
36 Value::Number(n) => {
37 Variable::Number(Decimal::from_str_exact(n.as_str()).expect("Allowed number"))
38 }
39 Value::String(s) => Variable::String(Rc::from(s.as_str())),
40 Value::Array(arr) => Variable::from_array(arr.iter().map(Variable::from).collect()),
41 Value::Object(obj) => Variable::from_object(
42 obj.iter()
43 .map(|(k, v)| (k.clone(), Variable::from(v)))
44 .collect(),
45 ),
46 }
47 }
48}
49
50impl From<Variable> for Value {
51 fn from(value: Variable) -> Self {
52 match value {
53 Variable::Null => Value::Null,
54 Variable::Bool(b) => Value::Bool(b),
55 Variable::Number(n) => Value::Number(Number::from_string_unchecked(n.to_string())),
56 Variable::String(s) => Value::String(s.to_string()),
57 Variable::Array(arr) => {
58 let vec = Rc::try_unwrap(arr)
59 .map(|a| a.into_inner())
60 .unwrap_or_else(|s| {
61 let borrowed = s.borrow();
62 borrowed.clone()
63 });
64
65 Value::Array(vec.into_iter().map(Value::from).collect())
66 }
67 Variable::Object(obj) => {
68 let hmap = Rc::try_unwrap(obj)
69 .map(|a| a.into_inner())
70 .unwrap_or_else(|s| {
71 let borrowed = s.borrow();
72 borrowed.clone()
73 });
74
75 Value::Object(hmap.into_iter().map(|(k, v)| (k, Value::from(v))).collect())
76 }
77 }
78 }
79}
80
81impl TryFrom<&Variable> for NaiveDateTime {
82 type Error = VMError;
83
84 fn try_from(value: &Variable) -> Result<Self, Self::Error> {
85 match value {
86 Variable::String(a) => date_time(a),
87 #[allow(deprecated)]
88 Variable::Number(a) => NaiveDateTime::from_timestamp_opt(
89 a.to_i64().ok_or_else(|| VMError::OpcodeErr {
90 opcode: "DateManipulation".into(),
91 message: "Failed to extract date".into(),
92 })?,
93 0,
94 )
95 .ok_or_else(|| VMError::ParseDateTimeErr {
96 timestamp: a.to_string(),
97 }),
98 _ => Err(VMError::OpcodeErr {
99 opcode: "DateManipulation".into(),
100 message: "Unsupported type".into(),
101 }),
102 }
103 }
104}