cel_parser/ast/
mod.rs

1use crate::reference::Val;
2use std::collections::BTreeMap;
3
4pub mod operators;
5
6pub struct Ast {
7    pub expr: IdedExpr,
8}
9
10#[derive(Clone, Debug, Default, PartialEq)]
11pub enum Expr {
12    #[default]
13    /// UnspecifiedExprKind represents an unset expression with no specified properties.
14    Unspecified,
15
16    /// CallKind represents a function call.
17    Call(CallExpr),
18
19    /// ComprehensionKind represents a comprehension expression generated by a macro.
20    Comprehension(ComprehensionExpr),
21
22    /// IdentKind represents a simple variable, constant, or type identifier.
23    Ident(String),
24
25    /// ListKind represents a list literal expression.
26    List(ListExpr),
27
28    /// LiteralKind represents a primitive scalar literal.
29    Literal(Val),
30
31    /// MapKind represents a map literal expression.
32    Map(MapExpr),
33
34    /// SelectKind represents a field selection expression.
35    Select(SelectExpr),
36
37    /// StructKind represents a struct literal expression.
38    Struct(StructExpr),
39}
40
41#[derive(Clone, Debug, PartialEq)]
42pub enum EntryExpr {
43    StructField(StructFieldExpr),
44    MapEntry(MapEntryExpr),
45}
46
47#[derive(Clone, Debug, Default, PartialEq)]
48pub struct IdedExpr {
49    pub id: u64,
50    pub expr: Expr,
51}
52
53#[derive(Clone, Debug, PartialEq)]
54pub struct IdedEntryExpr {
55    pub id: u64,
56    pub expr: EntryExpr,
57}
58
59#[derive(Clone, Debug, Default, PartialEq)]
60pub struct CallExpr {
61    pub func_name: String,
62    pub target: Option<Box<IdedExpr>>,
63    pub args: Vec<IdedExpr>,
64}
65
66#[derive(Clone, Debug, Default, PartialEq)]
67pub struct SelectExpr {
68    pub operand: Box<IdedExpr>,
69    pub field: String,
70    pub test: bool,
71}
72
73#[derive(Clone, Debug, Default, PartialEq)]
74pub struct StructExpr {
75    pub type_name: String,
76    pub entries: Vec<IdedEntryExpr>,
77}
78
79#[derive(Clone, Debug, Default, PartialEq)]
80pub struct MapExpr {
81    pub entries: Vec<IdedEntryExpr>,
82}
83
84#[derive(Clone, Debug, Default, PartialEq)]
85pub struct ListExpr {
86    pub elements: Vec<IdedExpr>,
87}
88
89#[derive(Clone, Debug, Default, PartialEq)]
90pub struct StructFieldExpr {
91    pub field: String,
92    pub value: IdedExpr,
93    pub optional: bool,
94}
95
96#[derive(Clone, Debug, Default, PartialEq)]
97pub struct MapEntryExpr {
98    pub key: IdedExpr,
99    pub value: IdedExpr,
100    pub optional: bool,
101}
102
103#[derive(Clone, Debug, Default, PartialEq)]
104pub struct ComprehensionExpr {
105    pub iter_range: Box<IdedExpr>,
106    pub iter_var: String,
107    pub iter_var2: Option<String>,
108    pub accu_var: String,
109    pub accu_init: Box<IdedExpr>,
110    pub loop_cond: Box<IdedExpr>,
111    pub loop_step: Box<IdedExpr>,
112    pub result: Box<IdedExpr>,
113}
114
115#[derive(Debug, Default)]
116pub struct SourceInfo {
117    offsets: BTreeMap<u64, OffsetRange>,
118    pub source: String,
119}
120
121impl SourceInfo {
122    pub fn add_offset(&mut self, id: u64, start: u32, stop: u32) {
123        self.offsets.insert(id, OffsetRange { start, stop });
124    }
125
126    pub fn offset_for(&self, id: u64) -> Option<(u32, u32)> {
127        self.offsets.get(&id).map(|range| (range.start, range.stop))
128    }
129
130    pub(crate) fn pos_for(&self, id: u64) -> Option<(isize, isize)> {
131        match self.offset_for(id) {
132            Some((start, _)) => {
133                let start = start as isize;
134                let mut offset = 0;
135                let mut line = 0;
136                for l in self.source.split_inclusive('\n') {
137                    line += 1;
138                    offset += l.len() as isize;
139                    if start < offset {
140                        return Some((line, start + (l.len() as isize) - offset + 1));
141                    }
142                }
143                None
144            }
145            None => None,
146        }
147    }
148
149    pub fn snippet(&self, line: isize) -> Option<&str> {
150        self.source.lines().nth(line as usize)
151    }
152}
153
154#[derive(Clone, Debug, Default, PartialEq)]
155pub struct OffsetRange {
156    pub start: u32,
157    pub stop: u32,
158}