darklua_core/nodes/statements/
if_statement.rs

1use std::mem;
2
3use crate::nodes::{Block, Expression, Token};
4
5#[derive(Clone, Debug, PartialEq, Eq)]
6pub struct IfBranchTokens {
7    pub elseif: Token,
8    pub then: Token,
9}
10
11impl IfBranchTokens {
12    super::impl_token_fns!(target = [elseif, then]);
13}
14
15#[derive(Clone, Debug, PartialEq, Eq)]
16pub struct IfBranch {
17    condition: Expression,
18    block: Block,
19    tokens: Option<IfBranchTokens>,
20}
21
22impl IfBranch {
23    pub fn new<E: Into<Expression>, B: Into<Block>>(condition: E, block: B) -> Self {
24        Self {
25            condition: condition.into(),
26            block: block.into(),
27            tokens: None,
28        }
29    }
30
31    pub fn empty<E: Into<Expression>>(condition: E) -> Self {
32        Self {
33            condition: condition.into(),
34            block: Block::default(),
35            tokens: None,
36        }
37    }
38
39    pub fn with_tokens(mut self, tokens: IfBranchTokens) -> Self {
40        self.tokens = Some(tokens);
41        self
42    }
43
44    #[inline]
45    pub fn set_tokens(&mut self, tokens: IfBranchTokens) {
46        self.tokens = Some(tokens);
47    }
48
49    #[inline]
50    pub fn get_tokens(&self) -> Option<&IfBranchTokens> {
51        self.tokens.as_ref()
52    }
53
54    #[inline]
55    pub fn get_block(&self) -> &Block {
56        &self.block
57    }
58
59    #[inline]
60    pub fn get_condition(&self) -> &Expression {
61        &self.condition
62    }
63
64    #[inline]
65    pub fn mutate_block(&mut self) -> &mut Block {
66        &mut self.block
67    }
68
69    #[inline]
70    pub fn take_block(&mut self) -> Block {
71        mem::take(&mut self.block)
72    }
73
74    #[inline]
75    pub fn mutate_condition(&mut self) -> &mut Expression {
76        &mut self.condition
77    }
78
79    super::impl_token_fns!(iter = [tokens]);
80}
81
82#[derive(Clone, Debug, PartialEq, Eq)]
83pub struct IfStatementTokens {
84    pub r#if: Token,
85    pub then: Token,
86    pub end: Token,
87    pub r#else: Option<Token>,
88}
89
90impl IfStatementTokens {
91    super::impl_token_fns!(
92        target = [r#if, then, end]
93        iter = [r#else]
94    );
95}
96
97#[derive(Clone, Debug, PartialEq, Eq)]
98pub struct IfStatement {
99    branches: Vec<IfBranch>,
100    else_block: Option<Block>,
101    tokens: Option<IfStatementTokens>,
102}
103
104impl IfStatement {
105    pub fn new(branches: Vec<IfBranch>, else_block: Option<Block>) -> Self {
106        Self {
107            branches,
108            else_block,
109            tokens: None,
110        }
111    }
112
113    pub fn create(condition: impl Into<Expression>, block: impl Into<Block>) -> Self {
114        Self {
115            branches: vec![IfBranch::new(condition, block)],
116            else_block: None,
117            tokens: None,
118        }
119    }
120
121    pub fn with_tokens(mut self, tokens: IfStatementTokens) -> Self {
122        self.tokens = Some(tokens);
123        self
124    }
125
126    #[inline]
127    pub fn set_tokens(&mut self, tokens: IfStatementTokens) {
128        self.tokens = Some(tokens);
129    }
130
131    #[inline]
132    pub fn get_tokens(&self) -> Option<&IfStatementTokens> {
133        self.tokens.as_ref()
134    }
135
136    #[inline]
137    pub fn mutate_tokens(&mut self) -> Option<&mut IfStatementTokens> {
138        self.tokens.as_mut()
139    }
140
141    pub fn with_branch(mut self, branch: IfBranch) -> Self {
142        self.branches.push(branch);
143        self
144    }
145
146    pub fn with_new_branch(
147        mut self,
148        condition: impl Into<Expression>,
149        block: impl Into<Block>,
150    ) -> Self {
151        self.branches.push(IfBranch::new(condition, block));
152        self
153    }
154
155    pub fn with_else_block<B: Into<Block>>(mut self, block: B) -> Self {
156        self.else_block.replace(block.into());
157        self
158    }
159
160    pub fn mutate_all_blocks(&mut self) -> Vec<&mut Block> {
161        let mut blocks: Vec<&mut Block> = self
162            .branches
163            .iter_mut()
164            .map(|branch| branch.mutate_block())
165            .collect();
166
167        if let Some(else_block) = &mut self.else_block {
168            blocks.push(else_block);
169        };
170
171        blocks
172    }
173
174    #[inline]
175    pub fn get_branches(&self) -> &Vec<IfBranch> {
176        &self.branches
177    }
178
179    #[inline]
180    pub fn iter_branches(&self) -> impl Iterator<Item = &IfBranch> {
181        self.branches.iter()
182    }
183
184    #[inline]
185    pub fn branch_count(&self) -> usize {
186        self.branches.len()
187    }
188
189    #[inline]
190    pub fn mutate_branches(&mut self) -> &mut Vec<IfBranch> {
191        &mut self.branches
192    }
193
194    #[inline]
195    pub fn push_new_branch(&mut self, condition: impl Into<Expression>, block: impl Into<Block>) {
196        self.branches
197            .push(IfBranch::new(condition.into(), block.into()));
198    }
199
200    #[inline]
201    pub fn push_branch(&mut self, branch: IfBranch) {
202        self.branches.push(branch);
203    }
204
205    #[inline]
206    pub fn get_else_block(&self) -> Option<&Block> {
207        self.else_block.as_ref()
208    }
209
210    #[inline]
211    pub fn mutate_else_block(&mut self) -> &mut Option<Block> {
212        &mut self.else_block
213    }
214
215    #[inline]
216    pub fn set_else_block(&mut self, block: impl Into<Block>) {
217        self.else_block = Some(block.into());
218    }
219
220    #[inline]
221    pub fn take_else_block(&mut self) -> Option<Block> {
222        self.else_block.take()
223    }
224
225    pub fn retain_branches_mut(&mut self, filter: impl FnMut(&mut IfBranch) -> bool) -> bool {
226        self.branches.retain_mut(filter);
227        if self.branches.is_empty() {
228            // an if statement requires at least one branch
229            self.branches.push(IfBranch::new(false, Block::default()));
230            true
231        } else {
232            false
233        }
234    }
235
236    super::impl_token_fns!(iter = [tokens, branches]);
237}