filter_expr_evaler/
value.rs1use std::sync::Arc;
2
3#[derive(Debug, Clone, PartialEq)]
4pub enum Value {
5 Str(Arc<String>),
7 I64(i64),
9 F64(f64),
11 Bool(bool),
13 Null,
15
16 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, }
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 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 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 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 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 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 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 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 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}