muninn_query/
ast.rs

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}