zen_expression/variable/types/
conv.rs1use crate::variable::types::VariableType;
2use serde_json::Value;
3use std::borrow::Cow;
4use std::ops::Deref;
5use std::rc::Rc;
6
7impl<'a> From<Cow<'a, Value>> for VariableType {
8 fn from(value: Cow<'a, Value>) -> Self {
9 match value.deref() {
10 Value::Null => VariableType::Null,
11 Value::Bool(_) => VariableType::Bool,
12 Value::Number(_) => VariableType::Number,
13 Value::String(_) => VariableType::String,
14 Value::Array(_) => {
15 let Value::Array(arr) = value.into_owned() else {
16 panic!("unexpected type of value, expected array");
17 };
18
19 VariableType::from(arr)
20 }
21 Value::Object(_) => {
22 let Value::Object(obj) = value.into_owned() else {
23 panic!("unexpected type of value, expected object");
24 };
25
26 VariableType::Object(
27 obj.into_iter()
28 .map(|(k, v)| (Rc::from(k.as_str()), Rc::new(v.into())))
29 .collect(),
30 )
31 }
32 }
33 }
34}
35
36impl From<Value> for VariableType {
37 fn from(value: Value) -> Self {
38 VariableType::from(Cow::Owned(value)).into()
39 }
40}
41
42impl From<&Value> for VariableType {
43 fn from(value: &Value) -> Self {
44 VariableType::from(Cow::Borrowed(value)).into()
45 }
46}
47
48impl From<Vec<Value>> for VariableType {
49 fn from(arr: Vec<Value>) -> Self {
50 if arr.len() == 0 {
51 return VariableType::Array(Rc::new(VariableType::Any));
52 }
53
54 let result_type = arr
55 .into_iter()
56 .fold(None, |acc: Option<VariableType>, b| match acc {
57 Some(a) => Some(a.merge(&VariableType::from(b))),
58 None => Some(VariableType::from(b)),
59 });
60
61 VariableType::Array(Rc::new(result_type.unwrap_or(VariableType::Any)))
62 }
63}
64
65impl From<&Vec<Value>> for VariableType {
66 fn from(arr: &Vec<Value>) -> Self {
67 if arr.len() == 0 {
68 return VariableType::Array(Rc::new(VariableType::Any));
69 }
70
71 let result_type = arr
72 .iter()
73 .fold(None, |acc: Option<VariableType>, b| match acc {
74 Some(a) => Some(a.merge(&VariableType::from(b))),
75 None => Some(VariableType::from(b)),
76 });
77
78 VariableType::Array(Rc::new(result_type.unwrap_or(VariableType::Any)))
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85 use serde_json::json;
86
87 #[test]
88 fn test_value_to_value_kind() {
89 assert_eq!(VariableType::from(json!(null)), VariableType::Null);
90 assert_eq!(VariableType::from(json!(true)), VariableType::Bool);
91 assert_eq!(VariableType::from(json!(42)), VariableType::Number);
92 assert_eq!(VariableType::from(json!("hello")), VariableType::String);
93 }
94}