darklua_core/nodes/expressions/
if_expression.rs

1use crate::nodes::Token;
2
3use super::Expression;
4
5/// Represents an if expression.
6#[derive(Clone, Debug, PartialEq, Eq)]
7pub struct IfExpression {
8    condition: Expression,
9    result: Expression,
10    else_result: Expression,
11    branches: Vec<ElseIfExpressionBranch>,
12    tokens: Option<IfExpressionTokens>,
13}
14
15impl IfExpression {
16    /// Creates a new if expression with the given condition, result, and else result.
17    pub fn new<E: Into<Expression>, E2: Into<Expression>, E3: Into<Expression>>(
18        condition: E,
19        result: E2,
20        else_result: E3,
21    ) -> Self {
22        Self {
23            condition: condition.into(),
24            result: result.into(),
25            else_result: else_result.into(),
26            branches: Vec::new(),
27            tokens: None,
28        }
29    }
30
31    /// Attaches tokens to this if expression.
32    pub fn with_tokens(mut self, tokens: IfExpressionTokens) -> Self {
33        self.tokens = Some(tokens);
34        self
35    }
36
37    /// Adds an elseif branch to this if expression.
38    pub fn with_branch<E: Into<Expression>, E2: Into<Expression>>(
39        mut self,
40        condition: E,
41        result: E2,
42    ) -> Self {
43        self.branches
44            .push(ElseIfExpressionBranch::new(condition, result));
45        self
46    }
47
48    /// Adds an elseif branch to this if expression.
49    #[inline]
50    pub fn push_branch(&mut self, branch: ElseIfExpressionBranch) {
51        self.branches.push(branch);
52    }
53
54    /// Attaches tokens to this if expression.
55    #[inline]
56    pub fn set_tokens(&mut self, tokens: IfExpressionTokens) {
57        self.tokens = Some(tokens);
58    }
59
60    /// Returns a reference to the tokens attached to this if expression, if any.
61    #[inline]
62    pub fn get_tokens(&self) -> Option<&IfExpressionTokens> {
63        self.tokens.as_ref()
64    }
65
66    /// Returns a reference to the condition of this if expression.
67    #[inline]
68    pub fn get_condition(&self) -> &Expression {
69        &self.condition
70    }
71
72    /// Returns a mutable reference to the condition of this if expression.
73    #[inline]
74    pub fn mutate_condition(&mut self) -> &mut Expression {
75        &mut self.condition
76    }
77
78    /// Returns a reference to the result of this if expression (returned when condition is true).
79    #[inline]
80    pub fn get_result(&self) -> &Expression {
81        &self.result
82    }
83
84    /// Returns a mutable reference to the result of this if expression.
85    #[inline]
86    pub fn mutate_result(&mut self) -> &mut Expression {
87        &mut self.result
88    }
89
90    /// Returns a reference to the else result of this if expression.
91    #[inline]
92    pub fn get_else_result(&self) -> &Expression {
93        &self.else_result
94    }
95
96    /// Returns a mutable reference to the else result of this if expression.
97    #[inline]
98    pub fn mutate_else_result(&mut self) -> &mut Expression {
99        &mut self.else_result
100    }
101
102    /// Returns whether this if expression has any elseif branches.
103    #[inline]
104    pub fn has_elseif_branch(&self) -> bool {
105        !self.branches.is_empty()
106    }
107
108    /// Returns an iterator over the elseif branches of this if expression.
109    #[inline]
110    pub fn iter_branches(&self) -> impl Iterator<Item = &ElseIfExpressionBranch> {
111        self.branches.iter()
112    }
113
114    /// Removes all elseif branches from this if expression.
115    #[inline]
116    pub fn clear_elseif_branches(&mut self) {
117        self.branches.clear();
118    }
119
120    /// Retains only the elseif branches that satisfy the predicate.
121    #[inline]
122    pub fn retain_elseif_branches_mut(
123        &mut self,
124        filter: impl FnMut(&mut ElseIfExpressionBranch) -> bool,
125    ) {
126        self.branches.retain_mut(filter);
127    }
128
129    /// Removes an elseif branch at the specified index and returns it.
130    pub fn remove_branch(&mut self, index: usize) -> Option<ElseIfExpressionBranch> {
131        if index < self.branches.len() {
132            Some(self.branches.remove(index))
133        } else {
134            None
135        }
136    }
137
138    /// Returns a mutable iterator over the elseif branches of this if expression.
139    #[inline]
140    pub fn iter_mut_branches(&mut self) -> impl Iterator<Item = &mut ElseIfExpressionBranch> {
141        self.branches.iter_mut()
142    }
143
144    /// Returns a mutable reference to the first token for this if expression,
145    /// creating it if missing.
146    pub fn mutate_first_token(&mut self) -> &mut Token {
147        if self.tokens.is_none() {
148            self.tokens = Some(IfExpressionTokens {
149                r#if: Token::from_content("if"),
150                then: Token::from_content("then"),
151                r#else: Token::from_content("else"),
152            });
153        }
154        &mut self.tokens.as_mut().unwrap().r#if
155    }
156
157    /// Returns a mutable reference to the last token for this if expression,
158    /// creating it if missing.
159    pub fn mutate_last_token(&mut self) -> &mut Token {
160        self.result.mutate_last_token()
161    }
162
163    super::impl_token_fns!(iter = [tokens, branches]);
164}
165
166/// Represents an elseif branch in an if expression.
167///
168/// Each branch has a condition and a result expression.
169#[derive(Clone, Debug, PartialEq, Eq)]
170pub struct ElseIfExpressionBranch {
171    condition: Expression,
172    result: Expression,
173    tokens: Option<ElseIfExpressionBranchTokens>,
174}
175
176impl ElseIfExpressionBranch {
177    /// Creates a new elseif branch with the given condition and result.
178    pub fn new<E: Into<Expression>, E2: Into<Expression>>(condition: E, result: E2) -> Self {
179        Self {
180            condition: condition.into(),
181            result: result.into(),
182            tokens: None,
183        }
184    }
185
186    /// Attaches tokens to this elseif branch.
187    #[inline]
188    pub fn set_tokens(&mut self, tokens: ElseIfExpressionBranchTokens) {
189        self.tokens = Some(tokens);
190    }
191
192    /// Returns a reference to the tokens attached to this elseif branch, if any.
193    #[inline]
194    pub fn get_tokens(&self) -> Option<&ElseIfExpressionBranchTokens> {
195        self.tokens.as_ref()
196    }
197
198    /// Returns a reference to the condition of this elseif branch.
199    #[inline]
200    pub fn get_condition(&self) -> &Expression {
201        &self.condition
202    }
203
204    /// Returns a mutable reference to the condition of this elseif branch.
205    #[inline]
206    pub fn mutate_condition(&mut self) -> &mut Expression {
207        &mut self.condition
208    }
209
210    /// Returns a reference to the result of this elseif branch.
211    #[inline]
212    pub fn get_result(&self) -> &Expression {
213        &self.result
214    }
215
216    /// Returns a mutable reference to the result of this elseif branch.
217    #[inline]
218    pub fn mutate_result(&mut self) -> &mut Expression {
219        &mut self.result
220    }
221
222    /// Consumes this branch and returns a tuple of (condition, result).
223    pub fn into_expressions(self) -> (Expression, Expression) {
224        (self.condition, self.result)
225    }
226
227    super::impl_token_fns!(iter = [tokens]);
228}
229
230/// Contains token information for an if expression.
231#[derive(Clone, Debug, PartialEq, Eq)]
232pub struct IfExpressionTokens {
233    /// The 'if' keyword token
234    pub r#if: Token,
235    /// The 'then' keyword token
236    pub then: Token,
237    /// The 'else' keyword token
238    pub r#else: Token,
239}
240
241impl IfExpressionTokens {
242    super::impl_token_fns!(target = [r#if, then, r#else]);
243}
244
245/// Contains token information for an elseif branch in an if expression.
246#[derive(Clone, Debug, PartialEq, Eq)]
247pub struct ElseIfExpressionBranchTokens {
248    /// The 'elseif' keyword token
249    pub elseif: Token,
250    /// The 'then' keyword token
251    pub then: Token,
252}
253
254impl ElseIfExpressionBranchTokens {
255    super::impl_token_fns!(target = [elseif, then]);
256}