cel_cxx/macros/
expr.rs

1use crate::Constant;
2
3/// A CEL expression node in the abstract syntax tree.
4///
5/// `Expr` represents a single node in a CEL expression tree during macro expansion.
6/// Each expression has a unique ID for source location tracking and an optional kind
7/// that determines what type of expression it is (constant, function call, etc.).
8///
9/// # Structure
10///
11/// An expression consists of:
12/// - `id`: A unique identifier for source position tracking and error reporting
13/// - `kind`: The specific type and content of the expression (or `None` for unspecified)
14///
15/// # Expression Kinds
16///
17/// The kind field determines the expression type:
18/// - [`Constant`]: Literal values (numbers, strings, booleans, etc.)
19/// - [`IdentExpr`]: Variable or identifier references
20/// - [`SelectExpr`]: Field selection (e.g., `obj.field`)
21/// - [`CallExpr`]: Function or method calls
22/// - [`ListExpr`]: List literals (e.g., `[1, 2, 3]`)
23/// - [`StructExpr`]: Struct literals (e.g., `Person{name: "Alice"}`)
24/// - [`MapExpr`]: Map literals (e.g., `{"key": "value"}`)
25/// - [`ComprehensionExpr`]: List/map comprehensions
26///
27/// # Examples
28///
29/// ```rust,no_run
30/// # use cel_cxx::macros::{Expr, ExprKind};
31/// # fn example(expr: &Expr) {
32/// // Access expression properties
33/// let id = expr.id();
34/// 
35/// // Check expression kind
36/// if let Some(kind) = expr.kind() {
37///     match kind {
38///         ExprKind::Constant(c) => println!("Constant: {:?}", c),
39///         ExprKind::Ident(i) => println!("Identifier: {}", i.name),
40///         ExprKind::Call(c) => println!("Function: {}", c.function),
41///         _ => {}
42///     }
43/// }
44/// # }
45/// ```
46#[derive(Debug, Default)]
47pub struct Expr {
48    id: i64,
49    kind: Option<Box<ExprKind>>,
50}
51
52impl std::ops::Deref for Expr {
53    type Target = ExprKind;
54
55    fn deref(&self) -> &Self::Target {
56        self.kind.as_ref().unwrap()
57    }
58}
59
60impl std::ops::DerefMut for Expr {
61    fn deref_mut(&mut self) -> &mut Self::Target {
62        self.kind.as_mut().unwrap()
63    }
64}
65
66impl Expr {
67    /// Returns the unique identifier of this expression.
68    ///
69    /// Expression IDs are used for source location tracking and correlating
70    /// expressions with their positions in the original source code.
71    pub fn id(&self) -> i64 {
72        self.id
73    }
74
75    /// Sets the unique identifier of this expression.
76    ///
77    /// This is typically handled by expression factory methods and rarely
78    /// needs to be called directly in user code.
79    pub fn set_id(&mut self, id: i64) {
80        self.id = id;
81    }
82
83    /// Returns a reference to the expression kind, if set.
84    ///
85    /// Returns `None` for unspecified expressions (expressions without a kind set).
86    ///
87    /// # Examples
88    ///
89    /// ```rust,no_run
90    /// # use cel_cxx::macros::{Expr, ExprKind};
91    /// # fn example(expr: &Expr) {
92    /// if let Some(kind) = expr.kind() {
93    ///     if kind.is_constant() {
94    ///         println!("This is a constant expression");
95    ///     }
96    /// }
97    /// # }
98    /// ```
99    pub fn kind(&self) -> Option<&ExprKind> {
100        self.kind.as_ref()
101            .map(|k| k.as_ref())
102    }
103
104    /// Sets the expression kind.
105    ///
106    /// This replaces any existing kind with the new one. Use this to construct
107    /// or modify expressions during macro expansion.
108    pub fn set_kind(&mut self, kind: ExprKind) {
109        self.kind = Some(Box::new(kind));
110    }
111
112    /// Clears the expression kind, making this an unspecified expression.
113    ///
114    /// This is rarely needed in practice; most expressions should have a kind.
115    pub fn clear_kind(&mut self) {
116        self.kind = None;
117    }
118}
119
120/// The kind/type of a CEL expression.
121///
122/// `ExprKind` is an enum representing all possible expression types in CEL.
123/// Each variant contains the specific data for that expression type.
124///
125/// # Variants
126///
127/// - [`Constant`]: Literal constant values
128/// - [`IdentExpr`]: Variable or identifier references
129/// - [`SelectExpr`]: Field selection or presence tests
130/// - [`CallExpr`]: Function or method calls
131/// - [`ListExpr`]: List literal expressions
132/// - [`StructExpr`]: Struct literal expressions
133/// - [`MapExpr`]: Map literal expressions
134/// - [`ComprehensionExpr`]: Comprehension expressions for list/map processing
135#[derive(Debug)]
136pub enum ExprKind {
137    /// A constant literal value.
138    Constant(Constant),
139    /// An identifier reference.
140    Ident(IdentExpr),
141    /// A field selection or presence test.
142    Select(SelectExpr),
143    /// A function or method call.
144    Call(CallExpr),
145    /// A list literal.
146    List(ListExpr),
147    /// A struct literal.
148    Struct(StructExpr),
149    /// A map literal.
150    Map(MapExpr),
151    /// A comprehension expression.
152    Comprehension(ComprehensionExpr),
153}
154
155impl ExprKind {
156    /// Returns `true` if this is a constant expression.
157    pub fn is_constant(&self) -> bool {
158        matches!(self, ExprKind::Constant(_))
159    }
160
161    /// Returns `true` if this is an identifier expression.
162    pub fn is_ident(&self) -> bool {
163        matches!(self, ExprKind::Ident(_))
164    }
165
166    /// Returns `true` if this is a select expression.
167    pub fn is_select(&self) -> bool {
168        matches!(self, ExprKind::Select(_))
169    }
170    
171    /// Returns `true` if this is a call expression.
172    pub fn is_call(&self) -> bool {
173        matches!(self, ExprKind::Call(_))
174    }
175
176    /// Returns `true` if this is a list expression.
177    pub fn is_list(&self) -> bool {
178        matches!(self, ExprKind::List(_))
179    }
180    
181    /// Returns `true` if this is a struct expression.
182    pub fn is_struct(&self) -> bool {
183        matches!(self, ExprKind::Struct(_))
184    }
185
186    /// Returns `true` if this is a map expression.
187    pub fn is_map(&self) -> bool {
188        matches!(self, ExprKind::Map(_))
189    }
190    
191    /// Returns `true` if this is a comprehension expression.
192    pub fn is_comprehension(&self) -> bool {
193        matches!(self, ExprKind::Comprehension(_))
194    }
195
196    /// Returns a reference to the constant value if this is a constant expression.
197    pub fn as_constant(&self) -> Option<&Constant> {
198        if let ExprKind::Constant(c) = self {
199            Some(c)
200        } else {
201            None
202        }
203    }
204
205    /// Returns a reference to the identifier if this is an identifier expression.
206    pub fn as_ident(&self) -> Option<&IdentExpr> {
207        if let ExprKind::Ident(i) = self {
208            Some(i)
209        } else {
210            None
211        }
212    }
213
214    /// Returns a reference to the select expression if this is a select expression.
215    pub fn as_select(&self) -> Option<&SelectExpr> {
216        if let ExprKind::Select(s) = self {
217            Some(s)
218        } else {
219            None
220        }
221    }
222
223    /// Returns a reference to the call expression if this is a call expression.
224    pub fn as_call(&self) -> Option<&CallExpr> {
225        if let ExprKind::Call(c) = self {
226            Some(c)
227        } else {
228            None
229        }
230    }
231
232    /// Returns a reference to the list expression if this is a list expression.
233    pub fn as_list(&self) -> Option<&ListExpr> {
234        if let ExprKind::List(l) = self {
235            Some(l)
236        } else {
237            None
238        }
239    }
240
241    /// Returns a reference to the struct expression if this is a struct expression.
242    pub fn as_struct(&self) -> Option<&StructExpr> {
243        if let ExprKind::Struct(s) = self {
244            Some(s)
245        } else {
246            None
247        }
248    }
249
250    /// Returns a reference to the map expression if this is a map expression.
251    pub fn as_map(&self) -> Option<&MapExpr> {
252        if let ExprKind::Map(m) = self {
253            Some(m)
254        } else {
255            None
256        }
257    }
258
259    /// Returns a reference to the comprehension expression if this is a comprehension expression.
260    pub fn as_comprehension(&self) -> Option<&ComprehensionExpr> {
261        if let ExprKind::Comprehension(c) = self {
262            Some(c)
263        } else {
264            None
265        }
266    }
267
268    /// Returns a mutable reference to the constant value if this is a constant expression.
269    pub fn as_constant_mut(&mut self) -> Option<&mut Constant> {
270        if let ExprKind::Constant(c) = self {
271            Some(c)
272        } else {
273            None
274        }
275    }
276    
277    /// Returns a mutable reference to the identifier if this is an identifier expression.
278    pub fn as_ident_mut(&mut self) -> Option<&mut IdentExpr> {
279        if let ExprKind::Ident(i) = self {
280            Some(i)
281        } else {
282            None
283        }
284    }
285    
286    /// Returns a mutable reference to the select expression if this is a select expression.
287    pub fn as_select_mut(&mut self) -> Option<&mut SelectExpr> {
288        if let ExprKind::Select(s) = self {
289            Some(s)
290        } else {
291            None
292        }
293    }
294    
295    /// Returns a mutable reference to the call expression if this is a call expression.
296    pub fn as_call_mut(&mut self) -> Option<&mut CallExpr> {
297        if let ExprKind::Call(c) = self {
298            Some(c)
299        } else {
300            None
301        }
302    }
303    
304    /// Returns a mutable reference to the list expression if this is a list expression.
305    pub fn as_list_mut(&mut self) -> Option<&mut ListExpr> {
306        if let ExprKind::List(l) = self {
307            Some(l)
308        } else {
309            None
310        }
311    }
312    
313    /// Returns a mutable reference to the struct expression if this is a struct expression.
314    pub fn as_struct_mut(&mut self) -> Option<&mut StructExpr> {
315        if let ExprKind::Struct(s) = self {
316            Some(s)
317        } else {
318            None
319        }
320    }
321    
322    /// Returns a mutable reference to the map expression if this is a map expression.
323    pub fn as_map_mut(&mut self) -> Option<&mut MapExpr> {
324        if let ExprKind::Map(m) = self {
325            Some(m)
326        } else {
327            None
328        }
329    }
330    
331    /// Returns a mutable reference to the comprehension expression if this is a comprehension expression.
332    pub fn as_comprehension_mut(&mut self) -> Option<&mut ComprehensionExpr> {
333        if let ExprKind::Comprehension(c) = self {
334            Some(c)
335        } else {
336            None
337        }
338    }
339}
340
341/// An identifier expression referencing a variable or constant.
342///
343/// Identifier expressions represent variable names in CEL, such as `x`, `my_var`,
344/// or `request.path`.
345#[derive(Debug)]
346pub struct IdentExpr {
347    /// The name of the identifier.
348    pub name: String,
349}
350
351/// A field selection expression.
352///
353/// Select expressions access fields on objects or maps. They can represent either:
354/// - Field access: `obj.field` (when `test_only` is `false`)
355/// - Presence test: `has(obj.field)` (when `test_only` is `true`)
356#[derive(Debug)]
357pub struct SelectExpr {
358    /// The expression being selected from (the object).
359    pub operand: Expr,
360    /// The name of the field being selected.
361    pub field: String,
362    /// If `true`, this is a presence test rather than field access.
363    pub test_only: bool,
364}
365
366/// A function or method call expression.
367///
368/// Call expressions represent both global function calls and method calls.
369/// For global calls, the `target` field is an unspecified expression.
370#[derive(Debug)]
371pub struct CallExpr {
372    /// The name of the function being called.
373    pub function: String,
374    /// The target expression for method calls (empty for global functions).
375    pub target: Expr,
376    /// The arguments passed to the function.
377    pub args: Vec<Expr>,
378}
379
380/// An element in a list expression.
381///
382/// List elements wrap expressions with metadata about whether they are optional.
383#[derive(Debug)]
384pub struct ListExprElement {
385    /// The expression value of this element.
386    pub expr: Expr,
387    /// If `true`, this element is omitted if the expression is undefined.
388    pub optional: bool,
389}
390
391/// A list literal expression.
392///
393/// List expressions create CEL list values, e.g., `[1, 2, 3]`.
394#[derive(Debug)]
395pub struct ListExpr {
396    /// The elements of the list.
397    pub elements: Vec<ListExprElement>,
398}
399
400/// A field in a struct expression.
401///
402/// Struct fields consist of a name, value expression, and optional flag.
403#[derive(Debug)]
404pub struct StructExprField {
405    /// The unique ID of this field for source tracking.
406    pub id: i64,
407    /// The name of the field.
408    pub name: String,
409    /// The expression providing the field value.
410    pub value: Expr,
411    /// If `true`, this field is omitted if the value is undefined.
412    pub optional: bool,
413}
414
415/// A struct literal expression.
416///
417/// Struct expressions create structured objects with named fields,
418/// e.g., `Person{name: "Alice", age: 30}`.
419#[derive(Debug)]
420pub struct StructExpr {
421    /// The name of the struct type.
422    pub name: String,
423    /// The fields of the struct.
424    pub fields: Vec<StructExprField>,
425}
426
427/// An entry in a map expression.
428///
429/// Map entries consist of key and value expressions, plus an optional flag.
430#[derive(Debug)]
431pub struct MapExprEntry {
432    /// The unique ID of this entry for source tracking.
433    pub id: i64,
434    /// The expression providing the map key.
435    pub key: Expr,
436    /// The expression providing the map value.
437    pub value: Expr,
438    /// If `true`, this entry is omitted if key or value is undefined.
439    pub optional: bool,
440}
441
442/// A map literal expression.
443///
444/// Map expressions create CEL map values, e.g., `{"key": "value", "foo": "bar"}`.
445#[derive(Debug)]
446pub struct MapExpr {
447    /// The entries of the map.
448    pub entries: Vec<MapExprEntry>,
449}
450
451/// A comprehension expression for list/map processing.
452///
453/// Comprehensions are CEL's powerful iteration construct, similar to list
454/// comprehensions in Python. They consist of iteration, accumulation, and
455/// result computation phases.
456///
457/// # Structure
458///
459/// A comprehension has:
460/// - One or two iteration variables that range over a collection
461/// - An accumulator variable that maintains state across iterations
462/// - A loop condition that determines when to continue
463/// - A loop step that updates the accumulator
464/// - A result expression that produces the final value
465///
466/// # Examples
467///
468/// Single variable: `[x * 2 | x in [1, 2, 3]]`
469/// - `iter_var`: `"x"`
470/// - `iter_range`: `[1, 2, 3]`
471/// - Result: `[2, 4, 6]`
472///
473/// Two variables (map iteration): `[k | k, v in {"a": 1, "b": 2}, v > 1]`
474/// - `iter_var`: `"k"` (key)
475/// - `iter_var2`: `"v"` (value)
476/// - `iter_range`: `{"a": 1, "b": 2}`
477/// - Result: `["b"]`
478#[derive(Debug)]
479pub struct ComprehensionExpr {
480    /// The first iteration variable name (required).
481    pub iter_var: String,
482    /// The second iteration variable name (empty string if not used).
483    pub iter_var2: String,
484    /// The expression providing the collection to iterate over.
485    pub iter_range: Expr,
486    /// The accumulator variable name.
487    pub accu_var: String,
488    /// The initial value of the accumulator.
489    pub accu_init: Expr,
490    /// The condition to continue iterating (often just `true`).
491    pub loop_condition: Expr,
492    /// The expression to update the accumulator each iteration.
493    pub loop_step: Expr,
494    /// The final expression computed from the accumulator.
495    pub result: Expr,
496}
497
498impl From<&Expr> for cxx::UniquePtr<crate::ffi::Expr> {
499    fn from(value: &Expr) -> Self {
500        use crate::ffi::Expr as FfiExpr;
501        use crate::ffi::Constant as FfiConstant;
502        use crate::ffi::CxxVectorExt;
503
504        let mut ffi_expr = FfiExpr::new();
505        ffi_expr.pin_mut().set_id(value.id());
506        match value.kind() {
507            None => {}
508            Some(ExprKind::Constant(constant)) => {
509                let ffi_constant: cxx::UniquePtr<FfiConstant> = constant.into();
510                ffi_expr.pin_mut()
511                    .set_const_expr(ffi_constant);
512            }
513            Some(ExprKind::Ident(ident)) => {
514                let mut ident_expr = ffi_expr.pin_mut().ident_expr_mut();
515                ident_expr.as_mut().set_name(ident.name.as_str().into());
516            }
517            Some(ExprKind::Select(select)) => {
518                let mut select_expr = ffi_expr.pin_mut().select_expr_mut();
519                select_expr.as_mut().set_operand((&select.operand).into());
520                select_expr.as_mut().set_field(select.field.as_str().into());
521                select_expr.as_mut().set_test_only(select.test_only);
522            }
523            Some(ExprKind::Call(call)) => {
524                let mut call_expr = ffi_expr.pin_mut().call_expr_mut();
525                call_expr.as_mut().set_function(call.function.as_str().into());
526                call_expr.as_mut().set_target((&call.target).into());
527                let mut args = call_expr.as_mut().args_mut();
528                for arg in &call.args {
529                    args.as_mut().push_unique(arg.into());
530                }
531            }
532            Some(ExprKind::List(list)) => {
533                let mut list_expr = ffi_expr.pin_mut().list_expr_mut();
534                let mut elements = list_expr.as_mut().elements_mut();
535                for element in &list.elements {
536                    elements.as_mut().push_unique(element.into());
537                }
538            }
539            Some(ExprKind::Struct(struct_)) => {
540                let mut struct_expr = ffi_expr.pin_mut().struct_expr_mut();
541                let mut fields = struct_expr.as_mut().fields_mut();
542                for field in &struct_.fields {
543                    fields.as_mut().push_unique(field.into());
544                }
545            }
546            Some(ExprKind::Map(map)) => {
547                let mut map_expr = ffi_expr.pin_mut().map_expr_mut();
548                let mut entries = map_expr.as_mut().entries_mut();
549                for entry in &map.entries {
550                    entries.as_mut().push_unique(entry.into());
551                }
552            }
553            Some(ExprKind::Comprehension(comprehension)) => {
554                let mut comprehension_expr = ffi_expr.pin_mut().comprehension_expr_mut();
555                comprehension_expr.as_mut().set_iter_var(comprehension.iter_var.as_str().into());
556                comprehension_expr.as_mut().set_iter_var2(comprehension.iter_var2.as_str().into());
557                comprehension_expr.as_mut().set_iter_range((&comprehension.iter_range).into());
558                comprehension_expr.as_mut().set_accu_var(comprehension.accu_var.as_str().into());
559                comprehension_expr.as_mut().set_accu_init((&comprehension.accu_init).into());
560                comprehension_expr.as_mut().set_loop_condition((&comprehension.loop_condition).into());
561                comprehension_expr.as_mut().set_loop_step((&comprehension.loop_step).into());
562                comprehension_expr.as_mut().set_result((&comprehension.result).into());
563            }
564        }
565        ffi_expr
566    }
567}
568
569impl From<Expr> for cxx::UniquePtr<crate::ffi::Expr> {
570    fn from(value: Expr) -> Self {
571        Self::from(&value)
572    }
573}
574
575impl From<&crate::ffi::Expr> for Expr {
576    fn from(value: &crate::ffi::Expr) -> Self {
577        use crate::ffi::ExprKindCase as FfiExprKindCase;
578
579        let mut expr = Expr::default();
580        expr.set_id(value.id());
581
582        let kind = match value.kind_case() {
583            FfiExprKindCase::Unspecified => None,
584            FfiExprKindCase::Constant => Some(ExprKind::Constant(Constant::from(value.const_expr()))),
585            FfiExprKindCase::Ident => Some(ExprKind::Ident(IdentExpr::from(value.ident_expr()))),
586            FfiExprKindCase::Select => Some(ExprKind::Select(SelectExpr::from(value.select_expr()))),
587            FfiExprKindCase::Call => Some(ExprKind::Call(CallExpr::from(value.call_expr()))),
588            FfiExprKindCase::List => Some(ExprKind::List(ListExpr::from(value.list_expr()))),
589            FfiExprKindCase::Struct => Some(ExprKind::Struct(StructExpr::from(value.struct_expr()))),
590            FfiExprKindCase::Map => Some(ExprKind::Map(MapExpr::from(value.map_expr()))),
591            FfiExprKindCase::Comprehension => Some(ExprKind::Comprehension(ComprehensionExpr::from(value.comprehension_expr()))),
592        };
593
594        if let Some(kind) = kind {
595            expr.set_kind(kind);
596        }
597        expr
598    }
599}
600
601impl From<cxx::UniquePtr<crate::ffi::Expr>> for Expr {
602    fn from(value: cxx::UniquePtr<crate::ffi::Expr>) -> Self {
603        Self::from(&*value)
604    }
605}
606
607impl From<&crate::ffi::IdentExpr> for IdentExpr {
608    fn from(value: &crate::ffi::IdentExpr) -> Self {
609        IdentExpr {
610            name: value.name().to_string(),
611        }
612    }
613}
614
615impl From<cxx::UniquePtr<crate::ffi::IdentExpr>> for IdentExpr {
616    fn from(value: cxx::UniquePtr<crate::ffi::IdentExpr>) -> Self {
617        Self::from(&*value)
618    }
619}
620
621impl From<&crate::ffi::SelectExpr> for SelectExpr {
622    fn from(value: &crate::ffi::SelectExpr) -> Self {
623        SelectExpr {
624            operand: Expr::from(value.operand()),
625            field: value.field().to_string(),
626            test_only: value.test_only(),
627        }
628    }
629}
630
631impl From<cxx::UniquePtr<crate::ffi::SelectExpr>> for SelectExpr {
632    fn from(value: cxx::UniquePtr<crate::ffi::SelectExpr>) -> Self {
633        Self::from(&*value)
634    }
635}
636
637impl From<&crate::ffi::CallExpr> for CallExpr {
638    fn from(value: &crate::ffi::CallExpr) -> Self {
639        CallExpr {
640            function: value.function().to_string(),
641            target: Expr::from(value.target()),
642            args: value.args()
643                .into_iter()
644                .map(|arg| Expr::from(arg))
645                .collect(),
646        }
647    }
648}
649
650impl From<cxx::UniquePtr<crate::ffi::CallExpr>> for CallExpr {
651    fn from(value: cxx::UniquePtr<crate::ffi::CallExpr>) -> Self {
652        Self::from(&*value)
653    }
654}
655
656impl From<&crate::ffi::ListExpr> for ListExpr {
657    fn from(value: &crate::ffi::ListExpr) -> Self {
658        ListExpr {
659            elements: value.elements()
660                .into_iter()
661                .map(|element| ListExprElement::from(element))
662                .collect(),
663        }
664    }
665}
666
667impl From<cxx::UniquePtr<crate::ffi::ListExpr>> for ListExpr {
668    fn from(value: cxx::UniquePtr<crate::ffi::ListExpr>) -> Self {
669        Self::from(&*value)
670    }
671}
672
673impl From<&crate::ffi::StructExpr> for StructExpr {
674    fn from(value: &crate::ffi::StructExpr) -> Self {
675        StructExpr {
676            name: value.name().to_string(),
677            fields: value.fields()
678                .into_iter()
679                .map(|field| StructExprField::from(field))
680                .collect(),
681        }
682    }
683}
684
685impl From<cxx::UniquePtr<crate::ffi::StructExpr>> for StructExpr {
686    fn from(value: cxx::UniquePtr<crate::ffi::StructExpr>) -> Self {
687        Self::from(&*value)
688    }
689}
690
691impl From<&crate::ffi::MapExpr> for MapExpr {
692    fn from(value: &crate::ffi::MapExpr) -> Self {
693        MapExpr {
694            entries: value.entries()
695                .into_iter()
696                .map(|entry| MapExprEntry::from(entry))
697                .collect(),
698        }
699    }
700}
701
702impl From<cxx::UniquePtr<crate::ffi::MapExpr>> for MapExpr {
703    fn from(value: cxx::UniquePtr<crate::ffi::MapExpr>) -> Self {
704        Self::from(&*value)
705    }
706}
707
708impl From<&crate::ffi::ComprehensionExpr> for ComprehensionExpr {
709    fn from(value: &crate::ffi::ComprehensionExpr) -> Self {
710        ComprehensionExpr {
711            iter_var: value.iter_var().to_string(),
712            iter_var2: value.iter_var2().to_string(),
713            iter_range: Expr::from(value.iter_range()),
714            accu_var: value.accu_var().to_string(),
715            accu_init: Expr::from(value.accu_init()),
716            loop_condition: Expr::from(value.loop_condition()),
717            loop_step: Expr::from(value.loop_step()),
718            result: Expr::from(value.result()),
719        }
720    }
721}
722
723impl From<cxx::UniquePtr<crate::ffi::ComprehensionExpr>> for ComprehensionExpr {
724    fn from(value: cxx::UniquePtr<crate::ffi::ComprehensionExpr>) -> Self {
725        Self::from(&*value)
726    }
727}
728
729impl From<&ListExprElement> for cxx::UniquePtr<crate::ffi::ListExprElement> {
730    fn from(value: &ListExprElement) -> Self {
731        use crate::ffi::ListExprElement as FfiListExprElement;
732
733        let mut ffi_element = FfiListExprElement::new();
734        ffi_element.pin_mut().set_expr((&value.expr).into());
735        ffi_element.pin_mut().set_optional(value.optional);
736        ffi_element
737    }
738}
739
740impl From<ListExprElement> for cxx::UniquePtr<crate::ffi::ListExprElement> {
741    fn from(element: ListExprElement) -> Self {
742        Self::from(&element)
743    }
744}
745
746impl From<&crate::ffi::ListExprElement> for ListExprElement {
747    fn from(value: &crate::ffi::ListExprElement) -> Self {
748        ListExprElement {
749            expr: Expr::from(value.expr()),
750            optional: value.optional(),
751        }
752    }
753}
754
755impl From<cxx::UniquePtr<crate::ffi::ListExprElement>> for ListExprElement {
756    fn from(value: cxx::UniquePtr<crate::ffi::ListExprElement>) -> Self {
757        Self::from(&*value)
758    }
759}
760
761impl From<&StructExprField> for cxx::UniquePtr<crate::ffi::StructExprField> {
762    fn from(value: &StructExprField) -> Self {
763        use crate::ffi::StructExprField as FfiStructExprField;
764
765        let mut ffi_field = FfiStructExprField::new();
766        ffi_field.pin_mut().set_id(value.id);
767        ffi_field.pin_mut().set_name(value.name.as_str().into());
768        ffi_field.pin_mut().set_value((&value.value).into());
769        ffi_field.pin_mut().set_optional(value.optional);
770        ffi_field
771    }
772}
773
774impl From<StructExprField> for cxx::UniquePtr<crate::ffi::StructExprField> {
775    fn from(value: StructExprField) -> Self {
776        Self::from(&value)
777    }
778}
779
780impl From<&crate::ffi::StructExprField> for StructExprField {
781    fn from(value: &crate::ffi::StructExprField) -> Self {
782        StructExprField {
783            id: value.id(),
784            name: value.name().to_string(),
785            value: Expr::from(value.value()),
786            optional: value.optional(),
787        }
788    }
789}
790
791impl From<cxx::UniquePtr<crate::ffi::StructExprField>> for StructExprField {
792    fn from(value: cxx::UniquePtr<crate::ffi::StructExprField>) -> Self {
793        Self::from(&*value)
794    }
795}
796
797impl From<&MapExprEntry> for cxx::UniquePtr<crate::ffi::MapExprEntry> {
798    fn from(value: &MapExprEntry) -> Self {
799        use crate::ffi::MapExprEntry as FfiMapExprEntry;
800        let mut ffi_entry = FfiMapExprEntry::new();
801        ffi_entry.pin_mut().set_id(value.id);
802        ffi_entry.pin_mut().set_key((&value.key).into());
803        ffi_entry.pin_mut().set_value((&value.value).into());
804        ffi_entry.pin_mut().set_optional(value.optional);
805        ffi_entry
806    }
807}
808
809impl From<MapExprEntry> for cxx::UniquePtr<crate::ffi::MapExprEntry> {
810    fn from(value: MapExprEntry) -> Self {
811        Self::from(&value)
812    }
813}
814
815impl From<&crate::ffi::MapExprEntry> for MapExprEntry {
816    fn from(value: &crate::ffi::MapExprEntry) -> Self {
817        MapExprEntry {
818            id: value.id(),
819            key: Expr::from(value.key()),
820            value: Expr::from(value.value()),
821            optional: value.optional(),
822        }
823    }
824}
825
826impl From<cxx::UniquePtr<crate::ffi::MapExprEntry>> for MapExprEntry {
827    fn from(value: cxx::UniquePtr<crate::ffi::MapExprEntry>) -> Self {
828        Self::from(&*value)
829    }
830}