vrl/parser/
ast.rs

1use std::{
2    collections::BTreeMap,
3    fmt,
4    hash::{Hash, Hasher},
5    iter::IntoIterator,
6    ops::Deref,
7    str::FromStr,
8};
9
10use crate::diagnostic::Span;
11use crate::path::{OwnedTargetPath, OwnedValuePath, PathPrefix};
12#[cfg(feature = "arbitrary")]
13use arbitrary::Arbitrary;
14use ordered_float::NotNan;
15
16use super::{Error, template_string::TemplateString};
17
18// -----------------------------------------------------------------------------
19// node
20// -----------------------------------------------------------------------------
21
22/// A wrapper type for a node, containing span details of that given node as it
23/// relates to the source input from which the node was generated.
24#[derive(Clone, Eq, Ord, PartialOrd)]
25pub struct Node<T> {
26    pub(crate) span: Span,
27    pub(crate) node: T,
28}
29
30impl<T> Node<T> {
31    pub fn map<R>(self, mut f: impl FnMut(T) -> R) -> Node<R> {
32        let Node { span, node } = self;
33
34        Node {
35            span,
36            node: f(node),
37        }
38    }
39
40    pub fn map_option<R>(self, mut f: impl FnMut(T) -> Option<R>) -> Option<Node<R>> {
41        let Node { span, node } = self;
42
43        let node = f(node)?;
44
45        Some(Node { span, node })
46    }
47
48    pub fn new(span: Span, node: T) -> Self {
49        Self { span, node }
50    }
51
52    /// Get a copy of the [`Span`] of the node.
53    pub fn span(&self) -> Span {
54        self.span
55    }
56
57    /// Get the starting byte of the node within the input source.
58    pub fn start(&self) -> usize {
59        self.span.start()
60    }
61
62    /// Get the ending byte of the node within the input source.
63    pub fn end(&self) -> usize {
64        self.span.end()
65    }
66
67    /// Get a reference to the inner node type `T`.
68    pub fn inner(&self) -> &T {
69        &self.node
70    }
71
72    // Consume the node, taking out the [`Span`] and inner node type `T`.
73    pub fn take(self) -> (Span, T) {
74        (self.span, self.node)
75    }
76
77    /// Consume the node, and get the inner node type `T`.
78    pub fn into_inner(self) -> T {
79        self.node
80    }
81
82    /// Consume the node and return a tuple consisting of the start, node type
83    /// `T` and the end position.
84    pub fn into_spanned(self) -> (usize, T, usize) {
85        let Self { span, node } = self;
86
87        (span.start(), node, span.end())
88    }
89
90    pub fn as_deref(&self) -> &T::Target
91    where
92        T: Deref,
93    {
94        self.as_ref()
95    }
96}
97
98impl<T: fmt::Debug> fmt::Debug for Node<T> {
99    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
100        self.node.fmt(f)
101    }
102}
103
104impl<T: fmt::Display> fmt::Display for Node<T> {
105    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106        self.node.fmt(f)
107    }
108}
109
110impl<T> Deref for Node<T> {
111    type Target = T;
112
113    fn deref(&self) -> &Self::Target {
114        &self.node
115    }
116}
117
118impl<T> AsRef<T> for Node<T> {
119    fn as_ref(&self) -> &T {
120        &self.node
121    }
122}
123
124impl<T: PartialEq> PartialEq for Node<T> {
125    fn eq(&self, other: &Self) -> bool {
126        self.node == other.node && self.span == other.span
127    }
128}
129
130impl<T: Hash> Hash for Node<T> {
131    fn hash<H: Hasher>(&self, state: &mut H) {
132        self.node.hash(state);
133        self.span.hash(state);
134    }
135}
136
137// -----------------------------------------------------------------------------
138// program
139// -----------------------------------------------------------------------------
140
141#[derive(Clone, PartialEq)]
142pub struct Program(pub Vec<Node<RootExpr>>);
143
144impl fmt::Debug for Program {
145    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
146        for expr in &self.0 {
147            writeln!(f, "{expr:?}")?;
148        }
149
150        Ok(())
151    }
152}
153
154impl fmt::Display for Program {
155    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
156        for expr in &self.0 {
157            writeln!(f, "{expr}")?;
158        }
159
160        Ok(())
161    }
162}
163
164impl Deref for Program {
165    type Target = [Node<RootExpr>];
166
167    fn deref(&self) -> &Self::Target {
168        self.0.as_slice()
169    }
170}
171
172impl IntoIterator for Program {
173    type Item = Node<RootExpr>;
174    type IntoIter = std::vec::IntoIter<Self::Item>;
175
176    fn into_iter(self) -> Self::IntoIter {
177        self.0.into_iter()
178    }
179}
180
181// -----------------------------------------------------------------------------
182// root expression
183// -----------------------------------------------------------------------------
184
185#[allow(clippy::large_enum_variant)]
186#[derive(Clone, PartialEq)]
187pub enum RootExpr {
188    Expr(Node<Expr>),
189
190    /// A special expression that is returned if a given expression could not be
191    /// parsed. This allows the parser to continue on to the next expression.
192    Error(Error),
193}
194
195impl fmt::Debug for RootExpr {
196    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
197        use RootExpr::{Error, Expr};
198
199        let value = match self {
200            Expr(v) => format!("{v:?}"),
201            Error(v) => format!("{v:?}"),
202        };
203
204        write!(f, "RootExpr({value})")
205    }
206}
207
208impl fmt::Display for RootExpr {
209    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
210        use RootExpr::{Error, Expr};
211
212        match self {
213            Expr(v) => v.fmt(f),
214            Error(v) => v.fmt(f),
215        }
216    }
217}
218
219// -----------------------------------------------------------------------------
220// expression
221// -----------------------------------------------------------------------------
222
223#[allow(clippy::large_enum_variant)]
224#[derive(Clone, PartialEq)]
225pub enum Expr {
226    Literal(Node<Literal>),
227    Container(Node<Container>),
228    IfStatement(Node<IfStatement>),
229    Op(Node<Op>),
230    Assignment(Node<Assignment>),
231    Query(Node<Query>),
232    FunctionCall(Node<FunctionCall>),
233    Variable(Node<Ident>),
234    Unary(Node<Unary>),
235    Abort(Node<Abort>),
236    Return(Node<Return>),
237}
238
239impl fmt::Debug for Expr {
240    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
241        use Expr::{
242            Abort, Assignment, Container, FunctionCall, IfStatement, Literal, Op, Query, Return,
243            Unary, Variable,
244        };
245
246        let value = match self {
247            Literal(v) => format!("{v:?}"),
248            Container(v) => format!("{v:?}"),
249            Op(v) => format!("{v:?}"),
250            IfStatement(v) => format!("{v:?}"),
251            Assignment(v) => format!("{v:?}"),
252            Query(v) => format!("{v:?}"),
253            FunctionCall(v) => format!("{v:?}"),
254            Variable(v) => format!("{v:?}"),
255            Unary(v) => format!("{v:?}"),
256            Abort(v) => format!("{v:?}"),
257            Return(v) => format!("{v:?}"),
258        };
259
260        write!(f, "Expr({value})")
261    }
262}
263
264impl fmt::Display for Expr {
265    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
266        use Expr::{
267            Abort, Assignment, Container, FunctionCall, IfStatement, Literal, Op, Query, Return,
268            Unary, Variable,
269        };
270
271        match self {
272            Literal(v) => v.fmt(f),
273            Container(v) => v.fmt(f),
274            Op(v) => v.fmt(f),
275            IfStatement(v) => v.fmt(f),
276            Assignment(v) => v.fmt(f),
277            Query(v) => v.fmt(f),
278            FunctionCall(v) => v.fmt(f),
279            Variable(v) => v.fmt(f),
280            Unary(v) => v.fmt(f),
281            Abort(v) => v.fmt(f),
282            Return(v) => v.fmt(f),
283        }
284    }
285}
286
287// -----------------------------------------------------------------------------
288// ident
289// -----------------------------------------------------------------------------
290
291#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
292pub struct Ident(pub(crate) String);
293
294impl Ident {
295    pub fn new(ident: impl Into<String>) -> Self {
296        Self(ident.into())
297    }
298
299    #[must_use]
300    pub fn into_inner(self) -> String {
301        self.0
302    }
303}
304
305impl Deref for Ident {
306    type Target = str;
307
308    fn deref(&self) -> &Self::Target {
309        &self.0
310    }
311}
312
313impl AsRef<str> for Ident {
314    fn as_ref(&self) -> &str {
315        &self.0
316    }
317}
318
319impl fmt::Display for Ident {
320    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
321        self.0.fmt(f)
322    }
323}
324
325impl fmt::Debug for Ident {
326    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
327        write!(f, "Ident({})", self.0)
328    }
329}
330
331impl From<String> for Ident {
332    fn from(ident: String) -> Self {
333        Ident(ident)
334    }
335}
336
337// -----------------------------------------------------------------------------
338// literals
339// -----------------------------------------------------------------------------
340
341#[derive(Clone, PartialEq, Eq)]
342pub enum Literal {
343    String(TemplateString),
344    RawString(String),
345    Integer(i64),
346    Float(NotNan<f64>),
347    Boolean(bool),
348    Regex(String),
349    Timestamp(String),
350    Null,
351}
352
353impl fmt::Display for Literal {
354    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
355        use Literal::{Boolean, Float, Integer, Null, RawString, Regex, String, Timestamp};
356
357        match self {
358            String(v) => write!(f, r#""{v}""#),
359            RawString(v) => write!(f, "s'{v}'"),
360            Integer(v) => v.fmt(f),
361            Float(v) => v.fmt(f),
362            Boolean(v) => v.fmt(f),
363            Regex(v) => write!(f, "r'{v}'"),
364            Timestamp(v) => write!(f, "t'{v}'"),
365            Null => f.write_str("null"),
366        }
367    }
368}
369
370impl fmt::Debug for Literal {
371    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
372        write!(f, "Literal({self})")
373    }
374}
375
376// -----------------------------------------------------------------------------
377// container
378// -----------------------------------------------------------------------------
379
380#[derive(Clone, PartialEq)]
381pub enum Container {
382    Group(Box<Node<Group>>),
383    Block(Node<Block>),
384    Array(Node<Array>),
385    Object(Node<Object>),
386}
387
388impl fmt::Display for Container {
389    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
390        use Container::{Array, Block, Group, Object};
391
392        match self {
393            Group(v) => v.fmt(f),
394            Block(v) => v.fmt(f),
395            Array(v) => v.fmt(f),
396            Object(v) => v.fmt(f),
397        }
398    }
399}
400
401impl fmt::Debug for Container {
402    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
403        use Container::{Array, Block, Group, Object};
404
405        let value = match self {
406            Group(v) => format!("{v:?}"),
407            Block(v) => format!("{v:?}"),
408            Array(v) => format!("{v:?}"),
409            Object(v) => format!("{v:?}"),
410        };
411
412        write!(f, "Container({value})")
413    }
414}
415
416// -----------------------------------------------------------------------------
417// block
418// -----------------------------------------------------------------------------
419
420#[derive(Clone, PartialEq)]
421pub struct Block(pub Vec<Node<Expr>>);
422
423impl Block {
424    #[must_use]
425    pub fn into_inner(self) -> Vec<Node<Expr>> {
426        self.0
427    }
428}
429
430impl IntoIterator for Block {
431    type Item = Node<Expr>;
432    type IntoIter = std::vec::IntoIter<Self::Item>;
433
434    fn into_iter(self) -> Self::IntoIter {
435        self.0.into_iter()
436    }
437}
438
439impl fmt::Display for Block {
440    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
441        f.write_str("{\n")?;
442
443        let mut iter = self.0.iter().peekable();
444        while let Some(expr) = iter.next() {
445            f.write_str("\t")?;
446            expr.fmt(f)?;
447            if iter.peek().is_some() {
448                f.write_str("\n")?;
449            }
450        }
451
452        f.write_str("\n}")
453    }
454}
455
456impl fmt::Debug for Block {
457    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
458        f.write_str("Block(")?;
459
460        let mut iter = self.0.iter().peekable();
461        while let Some(expr) = iter.next() {
462            expr.fmt(f)?;
463
464            if iter.peek().is_some() {
465                f.write_str("; ")?;
466            }
467        }
468
469        f.write_str(")")
470    }
471}
472
473// -----------------------------------------------------------------------------
474// group
475// -----------------------------------------------------------------------------
476
477#[derive(Clone, PartialEq)]
478pub struct Group(pub Node<Expr>);
479
480impl Group {
481    #[must_use]
482    pub fn into_inner(self) -> Node<Expr> {
483        self.0
484    }
485}
486
487impl fmt::Display for Group {
488    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
489        write!(f, "({})", self.0)
490    }
491}
492
493impl fmt::Debug for Group {
494    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
495        write!(f, "Group({:?})", self.0)
496    }
497}
498
499// -----------------------------------------------------------------------------
500// array
501// -----------------------------------------------------------------------------
502
503#[derive(Clone, PartialEq)]
504pub struct Array(pub(crate) Vec<Node<Expr>>);
505
506impl fmt::Display for Array {
507    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
508        let exprs = self
509            .0
510            .iter()
511            .map(std::string::ToString::to_string)
512            .collect::<Vec<_>>()
513            .join(", ");
514
515        write!(f, "[{exprs}]")
516    }
517}
518
519impl fmt::Debug for Array {
520    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
521        let exprs = self
522            .0
523            .iter()
524            .map(|e| format!("{e:?}"))
525            .collect::<Vec<_>>()
526            .join(", ");
527
528        write!(f, "Array([{exprs}])")
529    }
530}
531
532impl IntoIterator for Array {
533    type Item = Node<Expr>;
534    type IntoIter = std::vec::IntoIter<Self::Item>;
535
536    fn into_iter(self) -> Self::IntoIter {
537        self.0.into_iter()
538    }
539}
540
541impl FromIterator<Node<Expr>> for Array {
542    fn from_iter<T>(iter: T) -> Self
543    where
544        T: IntoIterator<Item = Node<Expr>>,
545    {
546        Self(iter.into_iter().collect())
547    }
548}
549
550// -----------------------------------------------------------------------------
551// object
552// -----------------------------------------------------------------------------
553
554#[derive(Clone, PartialEq)]
555pub struct Object(pub(crate) BTreeMap<Node<String>, Node<Expr>>);
556
557impl fmt::Display for Object {
558    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
559        let exprs = self
560            .0
561            .iter()
562            .map(|(k, v)| format!(r#""{k}": {v}"#))
563            .collect::<Vec<_>>()
564            .join(", ");
565
566        write!(f, "{{ {exprs} }}")
567    }
568}
569
570impl fmt::Debug for Object {
571    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
572        let exprs = self
573            .0
574            .iter()
575            .map(|(k, v)| format!(r#""{k}": {v:?}"#))
576            .collect::<Vec<_>>()
577            .join(", ");
578
579        write!(f, "{{ {exprs} }}")
580    }
581}
582
583impl IntoIterator for Object {
584    type Item = (Node<String>, Node<Expr>);
585    type IntoIter = std::collections::btree_map::IntoIter<Node<String>, Node<Expr>>;
586
587    fn into_iter(self) -> Self::IntoIter {
588        self.0.into_iter()
589    }
590}
591
592impl FromIterator<(Node<String>, Node<Expr>)> for Object {
593    fn from_iter<T>(iter: T) -> Self
594    where
595        T: IntoIterator<Item = (Node<String>, Node<Expr>)>,
596    {
597        Self(iter.into_iter().collect())
598    }
599}
600
601// -----------------------------------------------------------------------------
602// if statement
603// -----------------------------------------------------------------------------
604
605#[derive(Clone, PartialEq)]
606pub struct IfStatement {
607    pub predicate: Node<Predicate>,
608    pub if_node: Node<Block>,
609    pub else_node: Option<Node<Block>>,
610}
611
612impl fmt::Debug for IfStatement {
613    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
614        match &self.else_node {
615            Some(alt) => write!(f, "{:?} ? {:?} : {alt:?}", self.predicate, self.if_node),
616            None => write!(f, "{:?} ? {:?}", self.predicate, self.if_node),
617        }
618    }
619}
620
621impl fmt::Display for IfStatement {
622    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
623        f.write_str("if ")?;
624        self.predicate.fmt(f)?;
625        f.write_str(" ")?;
626        self.if_node.fmt(f)?;
627
628        if let Some(alt) = &self.else_node {
629            f.write_str(" else")?;
630            alt.fmt(f)?;
631        }
632
633        Ok(())
634    }
635}
636
637#[derive(Clone, PartialEq)]
638pub enum Predicate {
639    One(Box<Node<Expr>>),
640    Many(Vec<Node<Expr>>),
641}
642
643impl fmt::Display for Predicate {
644    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
645        match self {
646            Predicate::One(expr) => expr.fmt(f),
647            Predicate::Many(exprs) => {
648                f.write_str("(")?;
649
650                let mut iter = exprs.iter().peekable();
651                while let Some(expr) = iter.next() {
652                    expr.fmt(f)?;
653
654                    if iter.peek().is_some() {
655                        f.write_str("; ")?;
656                    }
657                }
658
659                f.write_str(")")
660            }
661        }
662    }
663}
664
665impl fmt::Debug for Predicate {
666    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
667        match self {
668            Predicate::One(expr) => write!(f, "Predicate({expr:?})"),
669            Predicate::Many(exprs) => {
670                f.write_str("Predicate(")?;
671
672                let mut iter = exprs.iter().peekable();
673                while let Some(expr) = iter.next() {
674                    expr.fmt(f)?;
675
676                    if iter.peek().is_some() {
677                        f.write_str("; ")?;
678                    }
679                }
680
681                f.write_str(")")
682            }
683        }
684    }
685}
686
687// -----------------------------------------------------------------------------
688// operation
689// -----------------------------------------------------------------------------
690
691#[derive(Clone, PartialEq)]
692pub struct Op(pub Box<Node<Expr>>, pub Node<Opcode>, pub Box<Node<Expr>>);
693
694impl fmt::Display for Op {
695    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
696        write!(f, "{} {} {}", self.0, self.1, self.2)
697    }
698}
699
700impl fmt::Debug for Op {
701    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
702        write!(f, "Op({:?} {} {:?})", self.0, self.1, self.2)
703    }
704}
705
706#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
707#[derive(Copy, Clone, Eq, PartialEq, Debug)]
708pub enum Opcode {
709    Mul,
710    Div,
711    Add,
712    Sub,
713    Or,
714    And,
715    Err,
716    Ne,
717    Eq,
718    Ge,
719    Gt,
720    Le,
721    Lt,
722    Merge,
723}
724
725impl fmt::Display for Opcode {
726    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
727        self.as_str().fmt(f)
728    }
729}
730
731impl Opcode {
732    #[must_use]
733    pub fn as_str(self) -> &'static str {
734        use Opcode::{Add, And, Div, Eq, Err, Ge, Gt, Le, Lt, Merge, Mul, Ne, Or, Sub};
735
736        match self {
737            Mul => "*",
738            Div => "/",
739            Add => "+",
740            Sub => "-",
741            Merge => "|",
742
743            Or => "||",
744            And => "&&",
745
746            Err => "??",
747
748            Ne => "!=",
749            Eq => "==",
750
751            Ge => ">=",
752            Gt => ">",
753            Le => "<=",
754            Lt => "<",
755        }
756    }
757}
758
759impl FromStr for Opcode {
760    type Err = ();
761
762    fn from_str(s: &str) -> Result<Self, ()> {
763        use Opcode::{Add, And, Div, Eq, Err, Ge, Gt, Le, Lt, Merge, Mul, Ne, Or, Sub};
764
765        let op = match s {
766            "*" => Mul,
767            "/" => Div,
768            "+" => Add,
769            "-" => Sub,
770
771            "||" => Or,
772            "&&" => And,
773
774            "??" => Err,
775
776            "!=" => Ne,
777            "==" => Eq,
778
779            ">=" => Ge,
780            ">" => Gt,
781            "<=" => Le,
782            "<" => Lt,
783            "|" => Merge,
784
785            _ => return std::result::Result::Err(()),
786        };
787
788        Ok(op)
789    }
790}
791
792// -----------------------------------------------------------------------------
793// assignment
794// -----------------------------------------------------------------------------
795
796#[derive(Clone, PartialEq)]
797#[allow(clippy::large_enum_variant)]
798pub enum Assignment {
799    Single {
800        target: Node<AssignmentTarget>,
801        op: AssignmentOp,
802        expr: Box<Node<Expr>>,
803    },
804    Infallible {
805        ok: Node<AssignmentTarget>,
806        err: Node<AssignmentTarget>,
807        op: AssignmentOp,
808        expr: Box<Node<Expr>>,
809    },
810    // TODO
811    // Compound {
812    //     target: Node<AssignmentTarget>,
813    //     op: Opcode,
814    //     expr: Box<Node<Expr>>,
815    // }
816}
817
818#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
819#[derive(Clone, PartialEq, Eq)]
820pub enum AssignmentOp {
821    Assign,
822    Merge,
823}
824
825impl fmt::Display for AssignmentOp {
826    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
827        use AssignmentOp::{Assign, Merge};
828
829        match self {
830            Assign => write!(f, "="),
831            Merge => write!(f, "|="),
832        }
833    }
834}
835
836impl fmt::Debug for AssignmentOp {
837    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
838        use AssignmentOp::{Assign, Merge};
839
840        match self {
841            Assign => write!(f, "AssignmentOp(=)"),
842            Merge => write!(f, "AssignmentOp(|=)"),
843        }
844    }
845}
846
847impl fmt::Display for Assignment {
848    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
849        use Assignment::{Infallible, Single};
850
851        match self {
852            Single { target, op, expr } => write!(f, "{target} {op} {expr}"),
853            Infallible { ok, err, op, expr } => write!(f, "{ok}, {err} {op} {expr}"),
854        }
855    }
856}
857
858impl fmt::Debug for Assignment {
859    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
860        use Assignment::{Infallible, Single};
861
862        match self {
863            Single { target, op, expr } => write!(f, "{target:?} {op:?} {expr:?}"),
864            Infallible { ok, err, op, expr } => {
865                write!(f, "Ok({ok:?}), Err({err:?}) {op:?} {expr:?}")
866            }
867        }
868    }
869}
870
871#[derive(Clone, PartialEq)]
872pub enum AssignmentTarget {
873    Noop,
874    Query(Query),
875    Internal(Ident, Option<OwnedValuePath>),
876    External(Option<OwnedTargetPath>),
877}
878
879impl AssignmentTarget {
880    #[must_use]
881    pub fn to_expr(&self, span: Span) -> Expr {
882        match self {
883            AssignmentTarget::Noop => Expr::Literal(Node::new(span, Literal::Null)),
884            AssignmentTarget::Query(query) => Expr::Query(Node::new(span, query.clone())),
885            AssignmentTarget::Internal(ident, Some(path)) => Expr::Query(Node::new(
886                span,
887                Query {
888                    target: Node::new(span, QueryTarget::Internal(ident.clone())),
889                    path: Node::new(span, path.clone()),
890                },
891            )),
892            AssignmentTarget::Internal(ident, None) => {
893                Expr::Variable(Node::new(span, ident.clone()))
894            }
895            AssignmentTarget::External(path) => Expr::Query(Node::new(
896                span,
897                Query {
898                    target: {
899                        let prefix = path.as_ref().map_or(PathPrefix::Event, |x| x.prefix);
900                        Node::new(span, QueryTarget::External(prefix))
901                    },
902                    path: Node::new(
903                        span,
904                        path.clone().map_or(OwnedValuePath::root(), |x| x.path),
905                    ),
906                },
907            )),
908        }
909    }
910}
911
912impl fmt::Display for AssignmentTarget {
913    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
914        use AssignmentTarget::{External, Internal, Noop, Query};
915
916        match self {
917            Noop => f.write_str("_"),
918            Query(query) => query.fmt(f),
919            Internal(ident, Some(path)) => write!(f, "{ident}{path}"),
920            Internal(ident, _) => ident.fmt(f),
921            External(Some(path)) => write!(f, "{path}"),
922            External(_) => f.write_str("."),
923        }
924    }
925}
926
927impl fmt::Debug for AssignmentTarget {
928    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
929        use AssignmentTarget::{External, Internal, Noop, Query};
930
931        match self {
932            Noop => f.write_str("Noop"),
933            Query(query) => query.fmt(f),
934            Internal(ident, Some(path)) => write!(f, "Internal({ident}{path})"),
935            Internal(ident, _) => write!(f, "Internal({ident})"),
936            External(Some(path)) => write!(f, "External({path})"),
937            External(_) => f.write_str("External(.)"),
938        }
939    }
940}
941
942// -----------------------------------------------------------------------------
943// query
944// -----------------------------------------------------------------------------
945
946#[derive(Clone, PartialEq)]
947pub struct Query {
948    pub target: Node<QueryTarget>,
949    pub path: Node<OwnedValuePath>,
950}
951
952impl fmt::Display for Query {
953    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
954        write!(f, "{}{}", self.target, self.path)
955    }
956}
957
958impl fmt::Debug for Query {
959    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
960        write!(f, "Query({:?}, {:?})", self.target, self.path)
961    }
962}
963
964#[derive(Clone, PartialEq)]
965pub enum QueryTarget {
966    Internal(Ident),
967    External(PathPrefix),
968    FunctionCall(FunctionCall),
969    Container(Container),
970}
971
972impl fmt::Display for QueryTarget {
973    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
974        use QueryTarget::{Container, External, FunctionCall, Internal};
975
976        match self {
977            Internal(v) => v.fmt(f),
978            External(prefix) => match prefix {
979                PathPrefix::Event => write!(f, "."),
980                PathPrefix::Metadata => write!(f, "&"),
981            },
982            FunctionCall(v) => v.fmt(f),
983            Container(v) => v.fmt(f),
984        }
985    }
986}
987
988impl fmt::Debug for QueryTarget {
989    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
990        use QueryTarget::{Container, External, FunctionCall, Internal};
991
992        match self {
993            Internal(v) => write!(f, "Internal({v:?})"),
994            External(prefix) => match prefix {
995                PathPrefix::Event => f.write_str("External(Event)"),
996                PathPrefix::Metadata => f.write_str("External(Metadata)"),
997            },
998            FunctionCall(v) => v.fmt(f),
999            Container(v) => v.fmt(f),
1000        }
1001    }
1002}
1003
1004// -----------------------------------------------------------------------------
1005// function call
1006// -----------------------------------------------------------------------------
1007
1008/// A function call expression.
1009///
1010/// It contains the identifier of the function, and any arguments passed into
1011/// the function call.
1012#[derive(Clone, PartialEq)]
1013pub struct FunctionCall {
1014    pub ident: Node<Ident>,
1015    pub abort_on_error: bool,
1016    pub arguments: Vec<Node<FunctionArgument>>,
1017    pub closure: Option<Node<FunctionClosure>>,
1018}
1019
1020impl fmt::Display for FunctionCall {
1021    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1022        self.ident.fmt(f)?;
1023        f.write_str("(")?;
1024
1025        let mut iter = self.arguments.iter().peekable();
1026        while let Some(arg) = iter.next() {
1027            arg.fmt(f)?;
1028
1029            if iter.peek().is_some() {
1030                f.write_str(", ")?;
1031            }
1032        }
1033
1034        f.write_str(")")?;
1035
1036        if let Some(closure) = &self.closure {
1037            f.write_str(" ")?;
1038            closure.fmt(f)?;
1039        }
1040
1041        Ok(())
1042    }
1043}
1044
1045impl fmt::Debug for FunctionCall {
1046    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1047        f.write_str("FunctionCall(")?;
1048        self.ident.fmt(f)?;
1049
1050        f.write_str("(")?;
1051
1052        let mut iter = self.arguments.iter().peekable();
1053        while let Some(arg) = iter.next() {
1054            arg.fmt(f)?;
1055
1056            if iter.peek().is_some() {
1057                f.write_str(", ")?;
1058            }
1059        }
1060
1061        f.write_str(")")?;
1062
1063        if let Some(closure) = &self.closure {
1064            f.write_str(" ")?;
1065            closure.fmt(f)?;
1066        }
1067
1068        f.write_str(")")
1069    }
1070}
1071
1072/// An argument passed to a function call.
1073///
1074/// The first value is an optional identifier provided for the argument, making
1075/// it a _keyword argument_ as opposed to a _positional argument_.
1076///
1077/// The second value is the expression provided as the argument.
1078#[derive(Clone, PartialEq)]
1079pub struct FunctionArgument {
1080    pub ident: Option<Node<Ident>>,
1081    pub expr: Node<Expr>,
1082}
1083
1084impl fmt::Display for FunctionArgument {
1085    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1086        if let Some(ident) = &self.ident {
1087            write!(f, "{ident}: ")?;
1088        }
1089
1090        self.expr.fmt(f)
1091    }
1092}
1093
1094impl fmt::Debug for FunctionArgument {
1095    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1096        if let Some(ident) = &self.ident {
1097            write!(f, "Argument({ident:?}: {:?})", self.expr)
1098        } else {
1099            write!(f, "Argument({:?})", self.expr)
1100        }
1101    }
1102}
1103
1104/// A closure attached to a function.
1105#[derive(Clone, PartialEq)]
1106pub struct FunctionClosure {
1107    pub variables: Vec<Node<Ident>>,
1108    pub block: Node<Block>,
1109}
1110
1111impl fmt::Display for FunctionClosure {
1112    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1113        f.write_str("-> |")?;
1114
1115        let mut iter = self.variables.iter().peekable();
1116        while let Some(var) = iter.next() {
1117            var.fmt(f)?;
1118
1119            if iter.peek().is_some() {
1120                f.write_str(", ")?;
1121            }
1122        }
1123
1124        f.write_str("| {\n")?;
1125
1126        let mut iter = self.block.0.iter().peekable();
1127        while let Some(expr) = iter.next() {
1128            f.write_str("\t")?;
1129            expr.fmt(f)?;
1130            if iter.peek().is_some() {
1131                f.write_str("\n")?;
1132            }
1133        }
1134
1135        f.write_str("\n}")
1136    }
1137}
1138
1139impl fmt::Debug for FunctionClosure {
1140    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1141        write!(f, "Closure(...)")
1142    }
1143}
1144
1145// -----------------------------------------------------------------------------
1146// unary
1147// -----------------------------------------------------------------------------
1148
1149#[derive(Clone, PartialEq)]
1150pub enum Unary {
1151    Not(Node<Not>),
1152}
1153
1154impl fmt::Display for Unary {
1155    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1156        use Unary::Not;
1157
1158        match self {
1159            Not(v) => v.fmt(f),
1160        }
1161    }
1162}
1163
1164impl fmt::Debug for Unary {
1165    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1166        use Unary::Not;
1167
1168        let value = match self {
1169            Not(v) => format!("{v:?}"),
1170        };
1171
1172        write!(f, "Unary({value})")
1173    }
1174}
1175
1176// -----------------------------------------------------------------------------
1177// not
1178// -----------------------------------------------------------------------------
1179
1180#[derive(Clone, PartialEq)]
1181pub struct Not(pub(crate) Node<()>, pub(crate) Box<Node<Expr>>);
1182
1183impl Not {
1184    #[must_use]
1185    pub fn take(self) -> (Node<()>, Box<Node<Expr>>) {
1186        (self.0, self.1)
1187    }
1188
1189    #[must_use]
1190    pub fn new(span: Span, expr: Node<Expr>) -> Self {
1191        Self(Node::new(span, ()), Box::new(expr))
1192    }
1193}
1194
1195impl fmt::Display for Not {
1196    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1197        write!(f, "!{}", self.1)
1198    }
1199}
1200
1201impl fmt::Debug for Not {
1202    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1203        write!(f, "Not({:?})", self.1)
1204    }
1205}
1206
1207// -----------------------------------------------------------------------------
1208// abort
1209// -----------------------------------------------------------------------------
1210
1211#[derive(Clone, PartialEq)]
1212pub struct Abort {
1213    pub message: Option<Box<Node<Expr>>>,
1214}
1215
1216impl fmt::Display for Abort {
1217    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1218        f.write_str(
1219            &self
1220                .message
1221                .as_ref()
1222                .map_or_else(|| "abort".to_owned(), |m| format!("abort: {m}")),
1223        )
1224    }
1225}
1226
1227impl fmt::Debug for Abort {
1228    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1229        write!(f, "Abort({:?})", self.message)
1230    }
1231}
1232
1233// -----------------------------------------------------------------------------
1234// return
1235// -----------------------------------------------------------------------------
1236
1237#[derive(Clone, PartialEq)]
1238pub struct Return {
1239    pub expr: Box<Node<Expr>>,
1240}
1241
1242impl fmt::Display for Return {
1243    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1244        write!(f, "return {}", self.expr)
1245    }
1246}
1247
1248impl fmt::Debug for Return {
1249    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1250        write!(f, "Return({:?})", self.expr)
1251    }
1252}