zen_types/variable_type/
mod.rs

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