1use std::fmt;
2
3use dyn_clone::{DynClone, clone_trait_object};
4
5pub use abort::Abort;
6pub use array::Array;
7pub use assignment::Assignment;
8pub use block::Block;
9pub use container::{Container, Variant};
10#[allow(clippy::module_name_repetitions)]
11pub use function::FunctionExpression;
12pub use function_argument::FunctionArgument;
13pub use function_call::FunctionCall;
14pub use group::Group;
15pub use if_statement::IfStatement;
16pub use literal::Literal;
17pub use noop::Noop;
18pub use not::Not;
19pub use object::Object;
20pub use op::Op;
21pub use predicate::Predicate;
22pub use query::{Query, Target};
23pub use r#return::Return;
24pub use unary::Unary;
25pub use variable::Variable;
26
27use crate::value::Value;
28
29#[allow(clippy::module_name_repetitions)]
30pub use super::ExpressionError;
31pub use super::Resolved;
32use super::state::{TypeInfo, TypeState};
33use super::{Context, TypeDef};
34
35mod abort;
36mod array;
37mod block;
38mod function_argument;
39mod group;
40mod if_statement;
41mod levenstein;
42mod noop;
43mod not;
44mod object;
45mod op;
46mod r#return;
47pub(crate) mod unary;
48mod variable;
49
50pub(crate) mod assignment;
51pub(crate) mod container;
52pub(crate) mod function;
53pub(crate) mod function_call;
54pub(crate) mod literal;
55pub(crate) mod predicate;
56pub mod query;
57
58#[allow(clippy::missing_errors_doc)]
59pub trait Expression: Send + Sync + fmt::Debug + DynClone {
60 fn resolve(&self, ctx: &mut Context) -> Resolved;
66
67 fn resolve_constant(&self, _state: &TypeState) -> Option<Value> {
72 None
73 }
74
75 fn type_def(&self, state: &TypeState) -> TypeDef {
81 self.type_info(state).result
82 }
83
84 fn type_info(&self, state: &TypeState) -> TypeInfo;
90
91 fn apply_type_info(&self, state: &mut TypeState) -> TypeDef {
94 let new_info = self.type_info(state);
95 *state = new_info.state;
96 new_info.result
97 }
98
99 fn format(&self) -> Option<String> {
105 None
106 }
107}
108
109clone_trait_object!(Expression);
110
111#[derive(Debug, Clone, PartialEq)]
112pub enum Expr {
113 Literal(Literal),
114 Container(Container),
115 IfStatement(IfStatement),
116 Op(Op),
117 Assignment(Assignment),
118 Query(Query),
119 FunctionCall(FunctionCall),
120 Variable(Variable),
121 Noop(Noop),
122 Unary(Unary),
123 Abort(Abort),
124 Return(Return),
125}
126
127impl Expr {
128 pub fn as_str(&self) -> &str {
129 use Expr::{
130 Abort, Assignment, Container, FunctionCall, IfStatement, Literal, Noop, Op, Query,
131 Return, Unary, Variable,
132 };
133 use container::Variant::{Array, Block, Group, Object};
134
135 match self {
136 Literal(..) => "literal",
137 Container(v) => match &v.variant {
138 Group(..) => "group",
139 Block(..) => "block",
140 Array(..) => "array",
141 Object(..) => "object",
142 },
143 IfStatement(..) => "if-statement",
144 Op(..) => "operation",
145 Assignment(..) => "assignment",
146 Query(..) => "query",
147 FunctionCall(..) => "function call",
148 Variable(..) => "variable call",
149 Noop(..) => "noop",
150 Unary(..) => "unary operation",
151 Abort(..) => "abort operation",
152 Return(..) => "return",
153 }
154 }
155
156 pub fn as_literal(
179 &self,
180 keyword: &'static str,
181 state: &TypeState,
182 ) -> Result<Value, super::function::Error> {
183 match self.resolve_constant(state) {
184 Some(value) => Ok(value),
185 None => Err(super::function::Error::UnexpectedExpression {
186 keyword,
187 expected: "literal",
188 expr: self.clone(),
189 }),
190 }
191 }
192
193 pub fn as_enum(
214 &self,
215 keyword: &'static str,
216 variants: Vec<Value>,
217 state: &TypeState,
218 ) -> Result<Value, super::function::Error> {
219 let value = self.as_literal(keyword, state)?;
220 variants.iter().find(|v| **v == value).cloned().ok_or(
221 super::function::Error::InvalidEnumVariant {
222 keyword,
223 value,
224 variants,
225 },
226 )
227 }
228}
229
230impl Expression for Expr {
231 fn resolve(&self, ctx: &mut Context) -> Resolved {
232 use Expr::{
233 Abort, Assignment, Container, FunctionCall, IfStatement, Literal, Noop, Op, Query,
234 Return, Unary, Variable,
235 };
236
237 match self {
238 Literal(v) => v.resolve(ctx),
239 Container(v) => v.resolve(ctx),
240 IfStatement(v) => v.resolve(ctx),
241 Op(v) => v.resolve(ctx),
242 Assignment(v) => v.resolve(ctx),
243 Query(v) => v.resolve(ctx),
244 FunctionCall(v) => v.resolve(ctx),
245 Variable(v) => v.resolve(ctx),
246 Noop(v) => v.resolve(ctx),
247 Unary(v) => v.resolve(ctx),
248 Abort(v) => v.resolve(ctx),
249 Return(v) => v.resolve(ctx),
250 }
251 }
252
253 fn resolve_constant(&self, state: &TypeState) -> Option<Value> {
254 use Expr::{
255 Abort, Assignment, Container, FunctionCall, IfStatement, Literal, Noop, Op, Query,
256 Return, Unary, Variable,
257 };
258
259 match self {
260 Literal(v) => Expression::resolve_constant(v, state),
261 Container(v) => Expression::resolve_constant(v, state),
262 IfStatement(v) => Expression::resolve_constant(v, state),
263 Op(v) => Expression::resolve_constant(v, state),
264 Assignment(v) => Expression::resolve_constant(v, state),
265 Query(v) => Expression::resolve_constant(v, state),
266 FunctionCall(v) => Expression::resolve_constant(v, state),
267 Variable(v) => Expression::resolve_constant(v, state),
268 Noop(v) => Expression::resolve_constant(v, state),
269 Unary(v) => Expression::resolve_constant(v, state),
270 Abort(v) => Expression::resolve_constant(v, state),
271 Return(v) => Expression::resolve_constant(v, state),
272 }
273 }
274
275 fn type_info(&self, state: &TypeState) -> TypeInfo {
276 use Expr::{
277 Abort, Assignment, Container, FunctionCall, IfStatement, Literal, Noop, Op, Query,
278 Return, Unary, Variable,
279 };
280
281 match self {
282 Literal(v) => v.type_info(state),
283 Container(v) => v.type_info(state),
284 IfStatement(v) => v.type_info(state),
285 Op(v) => v.type_info(state),
286 Assignment(v) => v.type_info(state),
287 Query(v) => v.type_info(state),
288 FunctionCall(v) => v.type_info(state),
289 Variable(v) => v.type_info(state),
290 Noop(v) => v.type_info(state),
291 Unary(v) => v.type_info(state),
292 Abort(v) => v.type_info(state),
293 Return(v) => v.type_info(state),
294 }
295 }
296}
297
298impl fmt::Display for Expr {
299 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
300 use Expr::{
301 Abort, Assignment, Container, FunctionCall, IfStatement, Literal, Noop, Op, Query,
302 Return, Unary, Variable,
303 };
304
305 match self {
306 Literal(v) => v.fmt(f),
307 Container(v) => v.fmt(f),
308 IfStatement(v) => v.fmt(f),
309 Op(v) => v.fmt(f),
310 Assignment(v) => v.fmt(f),
311 Query(v) => v.fmt(f),
312 FunctionCall(v) => v.fmt(f),
313 Variable(v) => v.fmt(f),
314 Noop(v) => v.fmt(f),
315 Unary(v) => v.fmt(f),
316 Abort(v) => v.fmt(f),
317 Return(v) => v.fmt(f),
318 }
319 }
320}
321
322impl From<Literal> for Expr {
325 fn from(literal: Literal) -> Self {
326 Expr::Literal(literal)
327 }
328}
329
330impl From<Container> for Expr {
331 fn from(container: Container) -> Self {
332 Expr::Container(container)
333 }
334}
335
336impl From<IfStatement> for Expr {
337 fn from(if_statement: IfStatement) -> Self {
338 Expr::IfStatement(if_statement)
339 }
340}
341
342impl From<Op> for Expr {
343 fn from(op: Op) -> Self {
344 Expr::Op(op)
345 }
346}
347
348impl From<Assignment> for Expr {
349 fn from(assignment: Assignment) -> Self {
350 Expr::Assignment(assignment)
351 }
352}
353
354impl From<Query> for Expr {
355 fn from(query: Query) -> Self {
356 Expr::Query(query)
357 }
358}
359
360impl From<FunctionCall> for Expr {
361 fn from(function_call: FunctionCall) -> Self {
362 Expr::FunctionCall(function_call)
363 }
364}
365
366impl From<Variable> for Expr {
367 fn from(variable: Variable) -> Self {
368 Expr::Variable(variable)
369 }
370}
371
372impl From<Noop> for Expr {
373 fn from(noop: Noop) -> Self {
374 Expr::Noop(noop)
375 }
376}
377
378impl From<Unary> for Expr {
379 fn from(unary: Unary) -> Self {
380 Expr::Unary(unary)
381 }
382}
383
384impl From<Abort> for Expr {
385 fn from(abort: Abort) -> Self {
386 Expr::Abort(abort)
387 }
388}
389
390impl From<Return> for Expr {
391 fn from(r#return: Return) -> Self {
392 Expr::Return(r#return)
393 }
394}
395
396impl From<Value> for Expr {
397 fn from(value: Value) -> Self {
398 use std::collections::BTreeMap;
399
400 use crate::value::Value::{
401 Array, Boolean, Bytes, Float, Integer, Null, Object, Regex, Timestamp,
402 };
403
404 match value {
405 Bytes(v) => Literal::from(v).into(),
406 Integer(v) => Literal::from(v).into(),
407 Float(v) => Literal::from(v).into(),
408 Boolean(v) => Literal::from(v).into(),
409 Object(v) => {
410 let object = super::expression::Object::from(
411 v.into_iter()
412 .map(|(k, v)| (k, v.into()))
413 .collect::<BTreeMap<_, _>>(),
414 );
415
416 Container::new(container::Variant::from(object)).into()
417 }
418 Array(v) => {
419 let array = super::expression::Array::from(
420 v.into_iter().map(Expr::from).collect::<Vec<_>>(),
421 );
422
423 Container::new(container::Variant::from(array)).into()
424 }
425 Timestamp(v) => Literal::from(v).into(),
426 Regex(v) => Literal::from(v).into(),
427 Null => Literal::from(()).into(),
428 }
429 }
430}
431
432#[allow(clippy::missing_errors_doc)]
434pub trait ExpressionExt {
435 fn map_resolve(&self, ctx: &mut Context) -> Result<Option<Value>, ExpressionError>;
436 fn map_resolve_with_default<F>(&self, ctx: &mut Context, default_fn: F) -> Resolved
437 where
438 F: FnOnce() -> Value;
439}
440
441impl ExpressionExt for Option<Box<dyn Expression>> {
442 fn map_resolve(&self, ctx: &mut Context) -> Result<Option<Value>, ExpressionError> {
443 self.as_ref().map(|expr| expr.resolve(ctx)).transpose()
444 }
445
446 fn map_resolve_with_default<F>(&self, ctx: &mut Context, default_fn: F) -> Resolved
447 where
448 F: FnOnce() -> Value,
449 {
450 Ok(self.map_resolve(ctx)?.unwrap_or_else(default_fn))
451 }
452}