toasty_core/stmt/
entry_mut.rs

1use super::{Expr, Value};
2
3/// A mutable reference to either an [`Expr`] or a [`Value`] within a
4/// composite structure.
5///
6/// This is the mutable counterpart to [`Entry`](super::Entry), used for
7/// in-place modification of nested expressions or values.
8///
9/// # Examples
10///
11/// ```ignore
12/// use toasty_core::stmt::{EntryMut, Expr, Value};
13///
14/// let mut expr = Expr::from(Value::from(42_i64));
15/// let mut entry = EntryMut::from(&mut expr);
16/// assert!(entry.is_expr());
17/// ```
18#[derive(Debug)]
19pub enum EntryMut<'a> {
20    /// A mutable reference to an expression.
21    Expr(&'a mut Expr),
22    /// A mutable reference to a value.
23    Value(&'a mut Value),
24}
25
26impl EntryMut<'_> {
27    /// Returns a reference to the contained expression, or `None`.
28    pub fn as_expr(&self) -> Option<&Expr> {
29        match self {
30            EntryMut::Expr(e) => Some(e),
31            _ => None,
32        }
33    }
34
35    /// Returns a reference to the contained expression, panicking if not an expression.
36    ///
37    /// # Panics
38    ///
39    /// Panics if this entry is not `EntryMut::Expr`.
40    #[track_caller]
41    pub fn as_expr_unwrap(&self) -> &Expr {
42        self.as_expr()
43            .unwrap_or_else(|| panic!("expected EntryMut::Expr; actual={self:#?}"))
44    }
45
46    /// Returns a mutable reference to the contained expression, or `None`.
47    pub fn as_expr_mut(&mut self) -> Option<&mut Expr> {
48        match self {
49            EntryMut::Expr(e) => Some(e),
50            _ => None,
51        }
52    }
53
54    /// Returns a mutable reference to the contained expression, panicking if not an expression.
55    ///
56    /// # Panics
57    ///
58    /// Panics if this entry is not `EntryMut::Expr`.
59    #[track_caller]
60    pub fn as_expr_mut_unwrap(&mut self) -> &mut Expr {
61        match self {
62            EntryMut::Expr(e) => e,
63            _ => panic!("expected EntryMut::Expr"),
64        }
65    }
66
67    /// Returns `true` if this entry holds an expression.
68    pub fn is_expr(&self) -> bool {
69        matches!(self, EntryMut::Expr(_))
70    }
71
72    /// Returns `true` if this entry holds a statement expression.
73    pub fn is_statement(&self) -> bool {
74        matches!(self, EntryMut::Expr(e) if e.is_stmt())
75    }
76
77    /// Returns `true` if this entry holds a concrete value.
78    pub fn is_value(&self) -> bool {
79        matches!(self, EntryMut::Value(_) | EntryMut::Expr(Expr::Value(_)))
80    }
81
82    /// Returns `true` if this entry holds a null value.
83    pub fn is_value_null(&self) -> bool {
84        matches!(
85            self,
86            EntryMut::Value(Value::Null) | EntryMut::Expr(Expr::Value(Value::Null))
87        )
88    }
89
90    /// Returns `true` if this entry is `Expr::Default`.
91    pub fn is_default(&self) -> bool {
92        matches!(self, EntryMut::Expr(Expr::Default))
93    }
94
95    /// Takes the contained expression or value, replacing it with a default.
96    pub fn take(&mut self) -> Expr {
97        match self {
98            EntryMut::Expr(expr) => expr.take(),
99            EntryMut::Value(value) => value.take().into(),
100        }
101    }
102
103    /// Replaces the contents of this entry with `expr`.
104    ///
105    /// # Panics
106    ///
107    /// Panics if this is a `Value` entry and `expr` is not `Expr::Value`.
108    pub fn insert(&mut self, expr: Expr) {
109        match self {
110            EntryMut::Expr(e) => **e = expr,
111            EntryMut::Value(e) => match expr {
112                Expr::Value(value) => **e = value,
113                _ => panic!("cannot store expression in value entry"),
114            },
115        }
116    }
117}
118
119impl<'a> From<&'a mut Expr> for EntryMut<'a> {
120    fn from(value: &'a mut Expr) -> Self {
121        EntryMut::Expr(value)
122    }
123}
124
125impl<'a> From<&'a mut Value> for EntryMut<'a> {
126    fn from(value: &'a mut Value) -> Self {
127        EntryMut::Value(value)
128    }
129}