zen_expression/variable/types/
conv.rs

1use 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}