1use std::fmt::{self, Formatter};
2
3#[derive(Clone)]
4pub struct Constraints {
5 pub constraints: Vec<ConstraintExpr>,
6 pub operator: ClauseOperator,
7}
8
9impl Constraints {
10 pub fn new_clause<T: Into<ConstraintExpr>>(op: ClauseOperator, v: Vec<T>) -> Constraints {
11 Constraints {
12 constraints: v.into_iter().map(|x| x.into()).collect(),
13 operator: op,
14 }
15 }
16 pub fn new_single<T: Into<ConstraintExpr>>(el: T) -> Constraints {
17 Constraints {
18 constraints: vec![el.into()],
19 operator: ClauseOperator::And,
20 }
21 }
22 pub fn or(self, c: Constraints) -> Constraints {
23 self.joined_with(c, ClauseOperator::Or)
24 }
25 pub fn and(self, c: Constraints) -> Constraints {
26 self.joined_with(c, ClauseOperator::And)
27 }
28 fn joined_with(self, c: Constraints, operator: ClauseOperator) -> Constraints {
29 if c.operator == operator && self.operator == operator {
30 Constraints {
31 constraints: [&self.constraints[..], &c.constraints[..]].concat(),
32 operator: self.operator,
33 }
34 } else {
35 Constraints::new_clause(operator, vec![self, c])
36 }
37 }
38 pub fn without<T: Into<ConstraintKey>>(self, removed_key: T) -> Constraints {
39 let op = self.operator;
40 let del_key = removed_key.into();
41 Constraints {
42 constraints: self
43 .into_iter()
44 .filter(|c| match c {
45 ConstraintExpr::KeyValue { key, .. } => *key != del_key,
46 _ => true,
47 })
48 .collect(),
49 operator: op,
50 }
51 }
52 pub fn filter_by_key<T: Into<ConstraintKey>>(&self, get_key: T) -> Option<Constraints> {
53 let k = get_key.into();
54 let v: Vec<_> = self
55 .constraints
56 .iter()
57 .cloned()
58 .filter(|e| match e {
59 ConstraintExpr::KeyValue { key, .. } => *key == k,
60 ConstraintExpr::Constraints(_) => false,
61 })
62 .collect();
63 match v.len() {
64 0 => None,
65 1 => Some(Self::new_single(v[0].clone())),
66 _ => Some(Self::new_clause(self.operator, v)),
67 }
68 }
69}
70
71impl fmt::Display for Constraints {
72 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
73 match self.constraints.len() {
74 0 => Ok(()),
75 1 => write!(f, "{}", self.constraints[0]),
76 _ => {
77 writeln!(f, "({}", self.operator)?;
78 for el in &self.constraints {
79 writeln!(f, " {}", el.to_string().replace('\n', "\n "))?;
80 }
81 write!(f, ")")
82 }
83 }
84 }
85}
86
87impl std::iter::IntoIterator for Constraints {
88 type Item = ConstraintExpr;
89 type IntoIter = std::vec::IntoIter<Self::Item>;
90
91 fn into_iter(self) -> Self::IntoIter {
92 self.constraints.into_iter()
93 }
94}
95
96#[derive(Copy, Clone, PartialEq, Eq)]
97pub enum ClauseOperator {
98 And,
99 Or,
100}
101
102impl fmt::Display for ClauseOperator {
103 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
104 write!(
105 f,
106 "{}",
107 match self {
108 ClauseOperator::And => "&",
109 ClauseOperator::Or => "|",
110 }
111 )
112 }
113}
114
115#[derive(Copy, Clone)]
116pub enum ConstraintOperator {
117 Equal,
118 NotEqual,
119 LessThan,
120 GreaterThan,
121}
122
123impl fmt::Display for ConstraintOperator {
124 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
125 write!(
126 f,
127 "{}",
128 match self {
129 ConstraintOperator::Equal => "=",
130 ConstraintOperator::NotEqual => "<>",
131 ConstraintOperator::LessThan => "<",
132 ConstraintOperator::GreaterThan => ">",
133 }
134 )
135 }
136}
137
138#[derive(Clone, PartialEq, Eq)]
139pub struct ConstraintKey(serde_json::Value);
140
141impl ConstraintKey {
142 pub fn new<T: Into<serde_json::Value>>(v: T) -> Self {
143 ConstraintKey(v.into())
144 }
145}
146
147impl<T: AsRef<str>> From<T> for ConstraintKey {
148 fn from(key: T) -> Self {
149 ConstraintKey::new(serde_json::Value::String(key.as_ref().to_string()))
150 }
151}
152
153pub type ConstraintValue = ConstraintKey;
154
155#[derive(Clone)]
157pub enum ConstraintExpr {
158 KeyValue {
159 key: ConstraintKey,
161 ops_values: Vec<(ConstraintOperator, ConstraintValue)>,
162 },
163 Constraints(Constraints),
164}
165
166impl From<ConstraintKey> for ConstraintExpr {
167 fn from(key: ConstraintKey) -> Self {
168 ConstraintExpr::KeyValue {
169 key,
170 ops_values: vec![],
171 }
172 }
173}
174
175impl From<Constraints> for ConstraintExpr {
176 fn from(key: Constraints) -> Self {
177 ConstraintExpr::Constraints(key)
178 }
179}
180
181impl fmt::Display for ConstraintExpr {
182 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
183 match self {
184 ConstraintExpr::KeyValue { key, ops_values } => {
185 if ops_values.is_empty() {
186 write!(f, "({})", key.0.as_str().unwrap_or(&key.0.to_string()))
187 } else {
188 for (op, val) in ops_values {
189 write!(f, "({}", key.0.as_str().unwrap_or(&key.0.to_string()))?;
190 write!(f, "{}", op)?;
191 write!(f, "{}", val.0.as_str().unwrap_or(&val.0.to_string()))?;
192 write!(f, ")")?
193 }
194 Ok(())
195 }
196 }
197 ConstraintExpr::Constraints(c) => write!(f, "{}", c),
198 }
199 }
200}
201
202impl ConstraintKey {
203 fn with_operator_value(
204 self,
205 operator: ConstraintOperator,
206 value: ConstraintValue,
207 ) -> ConstraintExpr {
208 ConstraintExpr::KeyValue {
209 key: self,
210 ops_values: vec![(operator, value)],
211 }
212 }
213 pub fn greater_than(self, value: ConstraintValue) -> ConstraintExpr {
214 self.with_operator_value(ConstraintOperator::GreaterThan, value)
215 }
216 pub fn less_than(self, value: ConstraintValue) -> ConstraintExpr {
217 self.with_operator_value(ConstraintOperator::LessThan, value)
218 }
219 pub fn equal_to(self, value: ConstraintValue) -> ConstraintExpr {
220 self.with_operator_value(ConstraintOperator::Equal, value)
221 }
222 pub fn not_equal_to(self, value: ConstraintValue) -> ConstraintExpr {
223 self.with_operator_value(ConstraintOperator::NotEqual, value)
224 }
225}
226
227#[macro_export]
228macro_rules! constraints [
229 () => {};
230 ($key:tt == $value:expr $(,)*) => {{ Constraints::new_single(ConstraintKey::new($key).equal_to(ConstraintKey::new($value))) }};
231 ($key:tt == $value:expr , $($r:tt)*) => {{ Constraints::new_single(ConstraintKey::new($key).equal_to(ConstraintKey::new($value))).and(constraints!( $($r)* )) }};
232 ($key:tt != $value:expr $(,)*) => {{ Constraints::new_single(ConstraintKey::new($key).not_equal_to(ConstraintKey::new($value))) }};
233 ($key:tt != $value:expr , $($r:tt)*) => {{ Constraints::new_single(ConstraintKey::new($key).not_equal_to(ConstraintKey::new($value))).and(constraints!( $($r)* )) }};
234 ($key:tt < $value:expr $(,)*) => {{ Constraints::new_single(ConstraintKey::new($key).less_than(ConstraintKey::new($value))) }};
235 ($key:tt < $value:expr , $($r:tt)*) => {{ Constraints::new_single(ConstraintKey::new($key).less_than(ConstraintKey::new($value))).and(constraints!( $($r)* )) }};
236 ($key:tt > $value:expr $(,)*) => {{ Constraints::new_single(ConstraintKey::new($key).greater_than(ConstraintKey::new($value))) }};
237 ($key:tt > $value:expr , $($r:tt)*) => {{ Constraints::new_single(ConstraintKey::new($key).greater_than(ConstraintKey::new($value))).and(constraints!( $($r)* )) }};
238 ($key:tt $(,)*) => {{ Constraints::new_single(ConstraintKey::new($key)) }};
239 ($key:tt , $($r:tt)*) => {{ Constraints::new_single(ConstraintKey::new($key)).and(constraints!( $($r)* )) }};
240 ($t:expr $(,)*) => { $t };
241 ($t:expr , $($r:tt)*) => {
242 $t.and(constraints!( $($r)* ))
243 };
244];