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
59impl BitAnd for Ast {
61 type Output = Ast;
62 fn bitand(self, rhs: Ast) -> Ast {
63 match (self, rhs) {
64 (Ast::And(mut a), Ast::And(b)) => {
65 a.extend(b);
66 Ast::And(a)
67 }
68 (Ast::And(mut a), rhs) => {
69 a.push(rhs);
70 Ast::And(a)
71 }
72 (lhs, rhs) => Ast::And(vec![lhs, rhs]),
73 }
74 }
75}
76
77impl BitOr for Ast {
79 type Output = Ast;
80 fn bitor(self, rhs: Ast) -> Ast {
81 match (self, rhs) {
82 (Ast::Or(mut a), Ast::Or(b)) => {
83 a.extend(b);
84 Ast::Or(a)
85 }
86 (Ast::Or(mut a), rhs) => {
87 a.push(rhs);
88 Ast::Or(a)
89 }
90 (lhs, rhs) => Ast::Or(vec![lhs, rhs]),
91 }
92 }
93}
94
95#[derive(Debug, Clone, PartialEq)]
96pub struct Constraint {
97 pub field: String,
98 pub operator: Operator,
99 pub value: Value,
100}
101
102#[derive(Debug, Clone, PartialEq)]
103pub enum Operator {
104 Eq,
105 Neq,
106 Lt,
107 Lte,
108 Gt,
109 Gte,
110 In,
111 Out,
112 Like,
113 Ilike,
114 Between,
115 Null,
116 NotNull,
117}
118
119#[derive(Debug, Clone, PartialEq)]
120pub enum Value {
121 Null,
122 Bool(bool),
123 Int(i64),
124 Float(f64),
125 String(String),
126 Date(String),
127 DateTime(String),
128 List(Vec<Value>),
129}
130
131impl From<bool> for Value {
132 fn from(v: bool) -> Self {
133 Value::Bool(v)
134 }
135}
136
137impl From<i32> for Value {
138 fn from(v: i32) -> Self {
139 Value::Int(v as i64)
140 }
141}
142
143impl From<i64> for Value {
144 fn from(v: i64) -> Self {
145 Value::Int(v)
146 }
147}
148
149impl From<f32> for Value {
150 fn from(v: f32) -> Self {
151 Value::Float(v as f64)
152 }
153}
154
155impl From<f64> for Value {
156 fn from(v: f64) -> Self {
157 Value::Float(v)
158 }
159}
160
161impl From<&str> for Value {
162 fn from(v: &str) -> Self {
163 Value::String(v.to_owned())
164 }
165}
166
167impl From<String> for Value {
168 fn from(v: String) -> Self {
169 Value::String(v)
170 }
171}