1use crate::ast::visit::AstVisitor;
2use chrono::{DateTime, FixedOffset, NaiveDate, NaiveDateTime};
3#[cfg(feature = "serde")]
4use serde_crate::{Deserialize, Serialize};
5
6#[derive(Debug, PartialEq, Clone)]
7#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8#[cfg_attr(
9 feature = "serde",
10 serde(crate = "serde_crate", tag = "kind", content = "value")
11)]
12pub enum Value {
13 Null,
14 Bool(bool),
15 Int(i64),
16 Float(f64),
17 String(String),
18 Date(NaiveDate),
19 DateTime(DateTime<FixedOffset>),
20 NaiveDateTime(NaiveDateTime),
21 RelativeTime(RelativeTime),
22}
23#[derive(Debug, PartialEq, Clone)]
24#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
25#[cfg_attr(
26 feature = "serde",
27 serde(crate = "serde_crate", tag = "kind", content = "value")
28)]
29pub enum RelativeTime {
30 Now,
31 Duration(Duration, TimeAnchor),
32}
33#[derive(Debug, PartialEq, Clone)]
34#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
35#[cfg_attr(
36 feature = "serde",
37 serde(crate = "serde_crate", tag = "kind", content = "value")
38)]
39pub enum Duration {
40 Seconds(i16),
41 Minutes(i16),
42 Hours(i16),
43 Days(i16),
44 Weeks(i16),
45 Months(i16),
46 Years(i16),
47}
48#[derive(Debug, PartialEq, Clone)]
49#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
50#[cfg_attr(
51 feature = "serde",
52 serde(crate = "serde_crate", tag = "kind", content = "value")
53)]
54pub enum TimeAnchor {
55 Ago,
56}
57
58pub type AbsolutePath = Vec<String>;
59#[derive(Debug, PartialEq, Clone)]
60#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
61#[cfg_attr(feature = "serde", serde(crate = "serde_crate"))]
62pub struct WildcardPath(pub Vec<PathElement>);
63#[derive(Debug, PartialEq, Clone)]
64#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
65#[cfg_attr(
66 feature = "serde",
67 serde(crate = "serde_crate", tag = "kind", content = "value")
68)]
69pub enum PathElement {
70 Field(String),
71 Wildcard,
72 RecursiveWildcard,
73}
74impl From<AbsolutePath> for WildcardPath {
75 fn from(vec: Vec<String>) -> WildcardPath {
76 WildcardPath(vec.into_iter().map(PathElement::Field).collect())
77 }
78}
79
80#[derive(Debug, PartialEq, Clone)]
81#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
82#[cfg_attr(feature = "serde", serde(crate = "serde_crate"))]
83pub struct UnaryExpression {
84 pub op: UnaryOperator,
85 pub expr: Expression,
86}
87#[derive(Debug, Copy, Clone, PartialEq)]
88#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
89#[cfg_attr(
90 feature = "serde",
91 serde(crate = "serde_crate", tag = "kind", content = "value")
92)]
93pub enum UnaryOperator {
94 Not,
95}
96
97#[derive(Debug, PartialEq, Clone)]
98#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
99#[cfg_attr(feature = "serde", serde(crate = "serde_crate"))]
100pub struct BinaryExpression {
101 pub lhs: Expression,
102 pub op: BinaryOperator,
103 pub rhs: Expression,
104}
105#[derive(Debug, Copy, Clone, PartialEq)]
106#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
107#[cfg_attr(
108 feature = "serde",
109 serde(crate = "serde_crate", tag = "kind", content = "value")
110)]
111pub enum BinaryOperator {
112 Eq,
113 Ne,
114 Lt,
115 Gt,
116 Lte,
117 Gte,
118 Match,
119 IMatch,
120 And,
121 Or,
122}
123impl BinaryOperator {
124 pub fn precedence(&self) -> u8 {
125 match self {
126 BinaryOperator::Or => 1,
127 BinaryOperator::And => 2,
128 BinaryOperator::Eq | BinaryOperator::Ne => 3,
129 BinaryOperator::Lt
130 | BinaryOperator::Gt
131 | BinaryOperator::Lte
132 | BinaryOperator::Gte
133 | BinaryOperator::Match
134 | BinaryOperator::IMatch => 4,
135 }
136 }
137}
138
139#[derive(Debug, PartialEq, Clone)]
140#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
141#[cfg_attr(
142 feature = "serde",
143 serde(crate = "serde_crate", tag = "kind", content = "value")
144)]
145pub enum Expression {
146 AbsolutePath(AbsolutePath),
147 WildcardPath(WildcardPath),
148 Value(Value),
149 UnaryExpression(Box<UnaryExpression>),
150 BinaryExpression(Box<BinaryExpression>),
151 Error(ErrorToken),
152}
153
154impl Expression {
155 pub fn is_error(&self) -> bool {
156 let mut is_error_visitor = IsErrorVisitor::default();
157 is_error_visitor.visit_expression(self);
158 is_error_visitor.is_error
159 }
160}
161
162#[derive(Debug, PartialEq, Clone)]
163#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
164#[cfg_attr(
165 feature = "serde",
166 serde(crate = "serde_crate", tag = "kind", content = "value")
167)]
168pub enum ErrorToken {
169 PathStart,
170 Identifier(String),
171 List(Vec<Expression>),
172 Unexpected,
173}
174
175#[derive(Default)]
176struct IsErrorVisitor {
177 is_error: bool,
178}
179
180impl<'a> AstVisitor<'a> for IsErrorVisitor {
181 fn visit_expression(&mut self, expression: &'a Expression) {
182 if !self.is_error {
183 visit::walk_expression(self, expression)
184 }
185 }
186
187 fn visit_error_token(&mut self, _: &'a ErrorToken) {
188 self.is_error = true;
189 }
190}
191
192pub mod visit {
193 use super::*;
194
195 pub trait AstVisitor<'a> {
196 fn visit_expression(&mut self, expression: &'a Expression) {
197 walk_expression(self, expression)
198 }
199 fn visit_unary_expression(&mut self, unary_expression: &'a UnaryExpression) {
200 walk_unary_expression(self, unary_expression)
201 }
202 fn visit_unary_operator(&mut self, _op: &'a UnaryOperator) {}
203 fn visit_binary_expression(&mut self, binary_expression: &'a BinaryExpression) {
204 walk_binary_expression(self, binary_expression)
205 }
206 fn visit_binary_operator(&mut self, _op: &'a BinaryOperator) {}
207 fn visit_absolute_path(&mut self, _path: &'a AbsolutePath) {}
208 fn visit_wildcard_path(&mut self, _path: &'a WildcardPath) {}
209 fn visit_value(&mut self, _value: &'a Value) {}
210
211 fn visit_error_token(&mut self, error: &'a ErrorToken) {
212 walk_error_token(self, error)
213 }
214
215 fn should_continue(&self) -> bool {
216 true
217 }
218 }
219
220 pub fn walk_expression<'a, V: AstVisitor<'a> + ?Sized>(
221 visitor: &mut V,
222 expression: &'a Expression,
223 ) -> () {
224 if !visitor.should_continue() {
225 return;
226 }
227 match *expression {
228 Expression::AbsolutePath(ref path) => visitor.visit_absolute_path(path),
229 Expression::WildcardPath(ref path) => visitor.visit_wildcard_path(path),
230 Expression::Value(ref value) => visitor.visit_value(value),
231 Expression::UnaryExpression(ref unary_expression) => {
232 visitor.visit_unary_expression(unary_expression)
233 }
234 Expression::BinaryExpression(ref binary_expression) => {
235 visitor.visit_binary_expression(binary_expression)
236 }
237 Expression::Error(ref error) => visitor.visit_error_token(error),
238 }
239 }
240
241 pub fn walk_unary_expression<'a, V: AstVisitor<'a> + ?Sized>(
242 visitor: &mut V,
243 unary_expression: &'a UnaryExpression,
244 ) -> () {
245 if !visitor.should_continue() {
246 return;
247 }
248 visitor.visit_unary_operator(&unary_expression.op);
249 if !visitor.should_continue() {
250 return;
251 }
252 visitor.visit_expression(&unary_expression.expr);
253 }
254
255 pub fn walk_binary_expression<'a, V: AstVisitor<'a> + ?Sized>(
256 visitor: &mut V,
257 binary_expression: &'a BinaryExpression,
258 ) -> () {
259 if !visitor.should_continue() {
260 return;
261 }
262 visitor.visit_expression(&binary_expression.lhs);
263 if !visitor.should_continue() {
264 return;
265 }
266 visitor.visit_binary_operator(&binary_expression.op);
267 if !visitor.should_continue() {
268 return;
269 }
270 visitor.visit_expression(&binary_expression.rhs);
271 }
272
273 pub fn walk_error_token<'a, V: AstVisitor<'a> + ?Sized>(
274 visitor: &mut V,
275 error: &'a ErrorToken,
276 ) -> () {
277 match *error {
278 ErrorToken::List(ref expressions) => {
279 for expression in expressions {
280 if !visitor.should_continue() {
281 return;
282 }
283 visitor.visit_expression(&expression);
284 }
285 }
286 _ => {}
287 }
288 }
289}