toasty_core/stmt/
expr_map.rs

1use super::Expr;
2
3/// A map/transform operation over a collection.
4///
5/// [`ExprMap`] applies a transformation expression to each item in a base
6/// collection. Within the `map` expression, `Expr::arg(n)` refers to elements
7/// of each item:
8///
9/// - For simple values, `arg(0)` is the item itself.
10/// - For records, `arg(0)` is field 0, `arg(1)` is field 1, etc.
11///
12/// # Examples
13///
14/// ## Simple values
15///
16/// ```text
17/// map([1, 2, 3], x => x == field)
18/// ```
19///
20/// Here `base` is `[1, 2, 3]` and `map` is `arg(0) == field`.
21///
22/// ## Records
23///
24/// ```text
25/// map([{1, 2}, {3, 4}], r => r.0 + r.1)
26/// ```
27///
28/// Here each item is a record with two fields. `arg(0)` refers to the first
29/// field and `arg(1)` refers to the second field of each record.
30#[derive(Debug, Clone, PartialEq)]
31pub struct ExprMap {
32    /// The collection expression to iterate over.
33    pub base: Box<Expr>,
34
35    /// The transformation to apply to each item. Use `Expr::arg(n)` to
36    /// reference elements of the current item being mapped.
37    pub map: Box<Expr>,
38}
39
40impl Expr {
41    /// Creates a map expression that applies `map` to each element of `base`.
42    pub fn map(base: impl Into<Self>, map: impl Into<Self>) -> Self {
43        ExprMap {
44            base: Box::new(base.into()),
45            map: Box::new(map.into()),
46        }
47        .into()
48    }
49
50    /// Returns a reference to the inner [`ExprMap`] if this is a map
51    /// expression, or `None` otherwise.
52    pub fn as_map(&self) -> Option<&ExprMap> {
53        match self {
54            Self::Map(expr) => Some(expr),
55            _ => None,
56        }
57    }
58
59    /// Returns a reference to the inner [`ExprMap`].
60    ///
61    /// # Panics
62    ///
63    /// Panics if `self` is not `Expr::Map`.
64    #[track_caller]
65    pub fn as_map_unwrap(&self) -> &ExprMap {
66        self.as_map()
67            .unwrap_or_else(|| panic!("expected Expr::Map; actual={self:#?}"))
68    }
69}
70
71impl From<ExprMap> for Expr {
72    fn from(value: ExprMap) -> Self {
73        Self::Map(value)
74    }
75}