1use std::ops::{BitAnd, BitOr};
2
3#[derive(Debug, Clone, PartialEq)]
5pub enum Ast {
6 And(Vec<Ast>),
7 Or(Vec<Ast>),
8 Constraint(Constraint),
9}
10
11impl Ast {
12 pub fn and(nodes: impl IntoIterator<Item = Ast>) -> Ast {
14 let v: Vec<_> = nodes.into_iter().collect();
15 assert!(!v.is_empty(), "Ast::and requires at least one node");
16 if v.len() == 1 {
17 v.into_iter().next().unwrap()
18 } else {
19 Ast::And(v)
20 }
21 }
22
23 pub fn or(nodes: impl IntoIterator<Item = Ast>) -> Ast {
25 let v: Vec<_> = nodes.into_iter().collect();
26 assert!(!v.is_empty(), "Ast::or requires at least one node");
27 if v.len() == 1 {
28 v.into_iter().next().unwrap()
29 } else {
30 Ast::Or(v)
31 }
32 }
33
34 pub fn try_and(nodes: impl IntoIterator<Item = Ast>) -> Option<Ast> {
36 let v: Vec<_> = nodes.into_iter().collect();
37 if v.is_empty() {
38 None
39 } else if v.len() == 1 {
40 v.into_iter().next()
41 } else {
42 Some(Ast::And(v))
43 }
44 }
45
46 pub fn try_or(nodes: impl IntoIterator<Item = Ast>) -> Option<Ast> {
48 let v: Vec<_> = nodes.into_iter().collect();
49 if v.is_empty() {
50 None
51 } else if v.len() == 1 {
52 v.into_iter().next()
53 } else {
54 Some(Ast::Or(v))
55 }
56 }
57
58 pub fn try_and_opts(nodes: impl IntoIterator<Item = Option<Ast>>) -> Option<Ast> {
73 Self::try_and(nodes.into_iter().flatten())
74 }
75
76 pub fn try_or_opts(nodes: impl IntoIterator<Item = Option<Ast>>) -> Option<Ast> {
78 Self::try_or(nodes.into_iter().flatten())
79 }
80}
81
82impl BitAnd for Ast {
84 type Output = Ast;
85 fn bitand(self, rhs: Ast) -> Ast {
86 match (self, rhs) {
87 (Ast::And(mut a), Ast::And(b)) => {
88 a.extend(b);
89 Ast::And(a)
90 }
91 (Ast::And(mut a), rhs) => {
92 a.push(rhs);
93 Ast::And(a)
94 }
95 (lhs, rhs) => Ast::And(vec![lhs, rhs]),
96 }
97 }
98}
99
100impl BitOr for Ast {
102 type Output = Ast;
103 fn bitor(self, rhs: Ast) -> Ast {
104 match (self, rhs) {
105 (Ast::Or(mut a), Ast::Or(b)) => {
106 a.extend(b);
107 Ast::Or(a)
108 }
109 (Ast::Or(mut a), rhs) => {
110 a.push(rhs);
111 Ast::Or(a)
112 }
113 (lhs, rhs) => Ast::Or(vec![lhs, rhs]),
114 }
115 }
116}
117
118#[derive(Debug, Clone, PartialEq)]
119pub struct Constraint {
120 pub field: String,
121 pub operator: Operator,
122 pub value: Value,
123}
124
125#[derive(Debug, Clone, PartialEq)]
126pub enum Operator {
127 Eq,
128 Neq,
129 Lt,
130 Lte,
131 Gt,
132 Gte,
133 In,
134 Out,
135 Like,
136 Ilike,
137 Between,
138 Null,
139 NotNull,
140}
141
142#[derive(Debug, Clone, PartialEq)]
143pub enum Value {
144 Null,
145 Bool(bool),
146 Int(i64),
147 Float(f64),
148 String(String),
149 Date(String),
150 DateTime(String),
151 List(Vec<Value>),
152}
153
154impl From<bool> for Value {
155 fn from(v: bool) -> Self {
156 Value::Bool(v)
157 }
158}
159
160impl From<i32> for Value {
161 fn from(v: i32) -> Self {
162 Value::Int(v as i64)
163 }
164}
165
166impl From<i64> for Value {
167 fn from(v: i64) -> Self {
168 Value::Int(v)
169 }
170}
171
172impl From<f32> for Value {
173 fn from(v: f32) -> Self {
174 Value::Float(v as f64)
175 }
176}
177
178impl From<f64> for Value {
179 fn from(v: f64) -> Self {
180 Value::Float(v)
181 }
182}
183
184impl From<&str> for Value {
185 fn from(v: &str) -> Self {
186 Value::String(v.to_owned())
187 }
188}
189
190impl From<String> for Value {
191 fn from(v: String) -> Self {
192 Value::String(v)
193 }
194}