toasty_core/stmt/
expr_list.rs

1use super::{Expr, Value};
2
3/// A list of expressions.
4///
5/// Represents an ordered collection of expressions that evaluate to a list of
6/// values.
7///
8/// # Examples
9///
10/// ```text
11/// list(a, b, c)  // a list containing expressions a, b, and c
12/// ```
13#[derive(Debug, Clone, PartialEq)]
14pub struct ExprList {
15    /// The expressions in the list.
16    pub items: Vec<Expr>,
17}
18
19impl Expr {
20    /// Creates a list expression from an iterator of items convertible to [`Expr`].
21    pub fn list<T>(items: impl IntoIterator<Item = T>) -> Self
22    where
23        T: Into<Self>,
24    {
25        ExprList {
26            items: items.into_iter().map(Into::into).collect(),
27        }
28        .into()
29    }
30
31    /// Creates a list expression from a pre-built vector of expressions.
32    pub fn list_from_vec(items: Vec<Self>) -> Self {
33        ExprList { items }.into()
34    }
35
36    /// Returns `true` if this expression is a list (either `Expr::List` or
37    /// `Expr::Value(Value::List(...))`).
38    pub fn is_list(&self) -> bool {
39        matches!(self, Self::List(_) | Self::Value(Value::List(_)))
40    }
41
42    /// Returns `true` if this expression is an empty list.
43    pub fn is_list_empty(&self) -> bool {
44        match self {
45            Self::List(list) => list.items.is_empty(),
46            Self::Value(Value::List(list)) => list.is_empty(),
47            _ => false,
48        }
49    }
50
51    /// Returns a reference to the inner [`ExprList`].
52    ///
53    /// # Panics
54    ///
55    /// Panics if `self` is not `Expr::List`.
56    #[track_caller]
57    pub fn as_list_unwrap(&self) -> &ExprList {
58        match self {
59            Self::List(list) => list,
60            _ => panic!("expected Expr::List(..) but was {self:#?}"),
61        }
62    }
63
64    /// Returns a mutable reference to the inner [`ExprList`].
65    ///
66    /// # Panics
67    ///
68    /// Panics if `self` is not `Expr::List`.
69    #[track_caller]
70    pub fn as_list_mut_unwrap(&mut self) -> &mut ExprList {
71        match self {
72            Self::List(list) => list,
73            _ => panic!("expected Expr::List(..) but was {self:#?}"),
74        }
75    }
76
77    /// Consumes the expression, returning `Some(ExprList)` if it is a list,
78    /// or `None` otherwise.
79    pub fn into_list(self) -> Option<ExprList> {
80        match self {
81            Self::List(list) => Some(list),
82            _ => None,
83        }
84    }
85}
86
87impl ExprList {
88    /// Returns `true` if the list contains no expressions.
89    pub fn is_empty(&self) -> bool {
90        self.items.is_empty()
91    }
92
93    /// Returns the number of expressions in the list.
94    pub fn len(&self) -> usize {
95        self.items.len()
96    }
97}
98
99impl From<ExprList> for Expr {
100    fn from(value: ExprList) -> Self {
101        Self::List(value)
102    }
103}
104
105impl From<Vec<Self>> for Expr {
106    fn from(value: Vec<Self>) -> Self {
107        Self::list_from_vec(value)
108    }
109}