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}