Skip to main content

zen_types/variable_type/
mod.rs

1mod conv;
2mod util;
3
4use ahash::HashMap;
5pub use ahash::HashMapExt as VariableMapExt;
6use serde::{Deserialize, Serialize};
7use std::cell::RefCell;
8use std::fmt::{Display, Write};
9use std::hash::{Hash, Hasher};
10use std::rc::Rc;
11
12type RcCell<T> = Rc<RefCell<T>>;
13
14#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
15pub enum VariableType {
16    Any,
17    Null,
18    Bool,
19    String,
20    Number,
21    Date,
22    Interval,
23    Array(Rc<VariableType>),
24    Object(RcCell<HashMap<Rc<str>, VariableType>>),
25
26    Const(Rc<str>),
27    Enum(Option<Rc<str>>, Vec<Rc<str>>),
28    Nullable(Rc<VariableType>),
29}
30
31impl VariableType {
32    pub fn array(self) -> Self {
33        Self::Array(Rc::new(self))
34    }
35}
36
37impl Default for VariableType {
38    fn default() -> Self {
39        VariableType::Null
40    }
41}
42
43impl Display for VariableType {
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        match self {
46            VariableType::Any => write!(f, "any"),
47            VariableType::Null => write!(f, "null"),
48            VariableType::Bool => write!(f, "bool"),
49            VariableType::String => write!(f, "string"),
50            VariableType::Number => write!(f, "number"),
51            VariableType::Date => write!(f, "date"),
52            VariableType::Interval => write!(f, "interval"),
53            VariableType::Const(c) => write!(f, "\"{c}\""),
54            VariableType::Enum(name, e) => {
55                if let Some(name) = name {
56                    return name.fmt(f);
57                }
58
59                let mut first = true;
60                for s in e.iter() {
61                    if !first {
62                        f.write_str(" | ")?;
63                    }
64
65                    f.write_char('"')?;
66                    f.write_str(s)?;
67                    f.write_char('"')?;
68                    first = false;
69                }
70
71                Ok(())
72            }
73            VariableType::Array(v) => write!(f, "{v}[]"),
74            VariableType::Object(_) => write!(f, "object"),
75            VariableType::Nullable(inner) => write!(f, "{inner}?"),
76        }
77    }
78}
79
80impl Hash for VariableType {
81    fn hash<H: Hasher>(&self, state: &mut H) {
82        match &self {
83            VariableType::Any => 0.hash(state),
84            VariableType::Null => 1.hash(state),
85            VariableType::Bool => 2.hash(state),
86            VariableType::String => 3.hash(state),
87            VariableType::Number => 4.hash(state),
88            VariableType::Date => 5.hash(state),
89            VariableType::Interval => 6.hash(state),
90            VariableType::Const(c) => {
91                7.hash(state);
92                c.hash(state)
93            }
94            VariableType::Enum(name, e) => {
95                8.hash(state);
96                name.hash(state);
97                e.hash(state)
98            }
99            VariableType::Array(arr) => {
100                9.hash(state);
101                arr.hash(state)
102            }
103            VariableType::Object(obj) => {
104                10.hash(state);
105
106                let obj = obj.borrow();
107                let mut pairs: Vec<_> = obj.iter().collect();
108                pairs.sort_by_key(|i| i.0);
109
110                Hash::hash(&pairs, state);
111            }
112            VariableType::Nullable(inner) => {
113                11.hash(state);
114                inner.hash(state);
115            }
116        }
117    }
118}