Skip to main content

filter_expr_evaler/
value.rs

1use std::sync::Arc;
2
3#[derive(Debug, Clone, PartialEq)]
4pub enum Value {
5    /// The string value.
6    Str(Arc<String>),
7    /// The integer value.
8    I64(i64),
9    /// The float value.
10    F64(f64),
11    /// The boolean value.
12    Bool(bool),
13    /// The null value.
14    Null,
15
16    /// The array value.
17    Array(Arc<Vec<Value>>),
18}
19
20impl PartialOrd for Value {
21    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
22        match (self, other) {
23            (Value::Str(a), Value::Str(b)) => a.partial_cmp(b),
24            (Value::I64(a), Value::I64(b)) => a.partial_cmp(b),
25            (Value::F64(a), Value::F64(b)) => a.partial_cmp(b),
26            (Value::Bool(a), Value::Bool(b)) => a.partial_cmp(b),
27            (Value::Null, Value::Null) => Some(std::cmp::Ordering::Equal),
28
29            (Value::F64(a), Value::I64(b)) => a.partial_cmp(&(*b as f64)),
30            (Value::I64(a), Value::F64(b)) => (*a as f64).partial_cmp(b),
31
32            (Value::Array(a), Value::Array(b)) => a.partial_cmp(b),
33
34            (Value::Null, _) => Some(std::cmp::Ordering::Greater),
35            (_, Value::Null) => Some(std::cmp::Ordering::Less),
36
37            _ => None, // Different types cannot be compared...
38        }
39    }
40}
41
42impl From<String> for Value {
43    fn from(val: String) -> Self {
44        Value::Str(Arc::new(val))
45    }
46}
47
48impl From<&str> for Value {
49    fn from(val: &str) -> Self {
50        Value::Str(Arc::new(val.to_string()))
51    }
52}
53
54impl From<i64> for Value {
55    fn from(val: i64) -> Self {
56        Value::I64(val)
57    }
58}
59
60impl From<f64> for Value {
61    fn from(val: f64) -> Self {
62        Value::F64(val)
63    }
64}
65
66impl From<bool> for Value {
67    fn from(val: bool) -> Self {
68        Value::Bool(val)
69    }
70}
71
72impl<T: Into<Value>> From<Vec<T>> for Value {
73    fn from(val: Vec<T>) -> Self {
74        Value::Array(Arc::new(val.into_iter().map(|item| item.into()).collect()))
75    }
76}
77
78impl Value {
79    pub fn str(s: impl Into<String>) -> Self {
80        Value::Str(Arc::new(s.into()))
81    }
82
83    pub fn i64(i: i64) -> Self {
84        Value::I64(i)
85    }
86
87    pub fn f64(f: f64) -> Self {
88        Value::F64(f)
89    }
90
91    pub fn bool(b: bool) -> Self {
92        Value::Bool(b)
93    }
94
95    pub fn null() -> Self {
96        Value::Null
97    }
98
99    pub fn array(items: impl Into<Vec<Value>>) -> Self {
100        Value::Array(Arc::new(items.into().into_iter().collect()))
101    }
102
103    pub fn typ(&self) -> ValueType {
104        match self {
105            Value::Str(_) => ValueType::Str,
106            Value::I64(_) => ValueType::I64,
107            Value::F64(_) => ValueType::F64,
108            Value::Bool(_) => ValueType::Bool,
109            Value::Null => ValueType::Null,
110            Value::Array(_) => ValueType::Array,
111        }
112    }
113}
114
115#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
116pub enum ValueType {
117    Str,
118    I64,
119    F64,
120    Bool,
121    Null,
122
123    Array,
124}
125
126#[cfg(test)]
127mod tests {
128    use crate::Value;
129
130    #[test]
131    fn test_expr_value_ordering() {
132        // Test string ordering.
133        assert!(Value::str("a") < Value::str("b"));
134        assert!(Value::str("a") <= Value::str("a"));
135        assert!(Value::str("b") > Value::str("a"));
136
137        // Test integer ordering.
138        assert!(Value::i64(1) < Value::i64(2));
139        assert!(Value::i64(1) <= Value::i64(1));
140        assert!(Value::i64(2) > Value::i64(1));
141
142        // Test float ordering.
143        assert!(Value::f64(1.0) < Value::f64(2.0));
144        assert!(Value::f64(1.0) <= Value::f64(1.0));
145        assert!(Value::f64(2.0) > Value::f64(1.0));
146
147        // Test boolean ordering.
148        assert!(Value::bool(false) < Value::bool(true));
149        assert!(Value::bool(false) <= Value::bool(false));
150        assert!(Value::bool(true) > Value::bool(false));
151
152        // Test Int and Float comparison.
153        assert!(Value::i64(1) < Value::f64(2.0));
154        assert!(Value::i64(2) > Value::f64(1.0));
155        assert!(Value::f64(1.0) < Value::i64(2));
156        assert!(Value::f64(2.0) > Value::i64(1));
157
158        // Test Null ordering.
159        assert!(Value::null() == Value::null());
160        assert!(Value::null() > Value::str("a"));
161        assert!(Value::str("a") < Value::null());
162        assert!(Value::null() > Value::i64(1));
163        assert!(Value::i64(1) < Value::null());
164
165        // Test array ordering.
166        let arr1 = Value::array([Value::i64(1), Value::i64(2)]);
167        let arr2 = Value::array([Value::i64(1), Value::i64(3)]);
168        assert!(arr1 < arr2);
169        assert!(arr1 <= arr1);
170        assert!(arr2 > arr1);
171
172        // Test incompatible types (should return None).
173        assert!(Value::str("a").partial_cmp(&Value::i64(1)).is_none());
174        assert!(Value::i64(1).partial_cmp(&Value::bool(true)).is_none());
175        assert!(Value::str("a").partial_cmp(&Value::bool(false)).is_none());
176        assert!(Value::array([]).partial_cmp(&Value::i64(1)).is_none());
177    }
178}