darklua_core/nodes/statements/
last_statement.rs1use crate::nodes::{Expression, Token};
2
3#[derive(Clone, Debug, PartialEq, Eq)]
5pub struct ReturnTokens {
6 pub r#return: Token,
7 pub commas: Vec<Token>,
9}
10
11impl ReturnTokens {
12 super::impl_token_fns!(
13 target = [r#return]
14 iter = [commas]
15 );
16}
17
18#[derive(Clone, Debug, Default, PartialEq, Eq)]
20pub struct ReturnStatement {
21 expressions: Vec<Expression>,
22 tokens: Option<ReturnTokens>,
23}
24
25impl ReturnStatement {
26 pub fn new(expressions: Vec<Expression>) -> Self {
28 Self {
29 expressions,
30 tokens: None,
31 }
32 }
33
34 pub fn one<E: Into<Expression>>(expression: E) -> Self {
44 Self {
45 expressions: vec![expression.into()],
46 tokens: None,
47 }
48 }
49
50 pub fn with_expression<E: Into<Expression>>(mut self, expression: E) -> Self {
52 self.expressions.push(expression.into());
53 self
54 }
55
56 #[inline]
58 pub fn iter_expressions(&self) -> impl Iterator<Item = &Expression> {
59 self.expressions.iter()
60 }
61
62 #[inline]
64 pub fn into_iter_expressions(self) -> impl Iterator<Item = Expression> {
65 self.expressions.into_iter()
66 }
67
68 #[inline]
70 pub fn iter_mut_expressions(&mut self) -> impl Iterator<Item = &mut Expression> {
71 self.expressions.iter_mut()
72 }
73
74 #[inline]
76 pub fn is_empty(&self) -> bool {
77 self.expressions.is_empty()
78 }
79
80 #[inline]
82 pub fn len(&self) -> usize {
83 self.expressions.len()
84 }
85
86 pub fn with_tokens(mut self, tokens: ReturnTokens) -> Self {
88 self.tokens = Some(tokens);
89 self
90 }
91
92 #[inline]
94 pub fn set_tokens(&mut self, tokens: ReturnTokens) {
95 self.tokens = Some(tokens);
96 }
97
98 #[inline]
100 pub fn get_tokens(&self) -> Option<&ReturnTokens> {
101 self.tokens.as_ref()
102 }
103
104 #[inline]
106 pub fn mutate_tokens(&mut self) -> Option<&mut ReturnTokens> {
107 self.tokens.as_mut()
108 }
109
110 pub fn mutate_first_token(&mut self) -> &mut Token {
112 self.set_default_tokens();
113 &mut self.tokens.as_mut().unwrap().r#return
114 }
115
116 pub fn mutate_last_token(&mut self) -> &mut Token {
119 if self.is_empty() {
120 self.set_default_tokens();
121 &mut self.tokens.as_mut().unwrap().r#return
122 } else {
123 self.expressions.last_mut().unwrap().mutate_last_token()
124 }
125 }
126
127 fn set_default_tokens(&mut self) {
128 if self.tokens.is_none() {
129 self.tokens = Some(ReturnTokens {
130 r#return: Token::from_content("return"),
131 commas: Vec::new(),
132 });
133 }
134 }
135
136 super::impl_token_fns!(iter = [tokens]);
137}
138
139#[derive(Clone, Debug, PartialEq, Eq)]
141pub enum LastStatement {
142 Break(Option<Token>),
143 Continue(Option<Token>),
144 Return(ReturnStatement),
145}
146
147impl LastStatement {
148 #[inline]
150 pub fn new_break() -> Self {
151 Self::Break(None)
152 }
153
154 #[inline]
156 pub fn new_continue() -> Self {
157 Self::Continue(None)
158 }
159
160 pub fn mutate_first_token(&mut self) -> &mut Token {
162 match self {
163 LastStatement::Break(token_opt) => {
164 if token_opt.is_none() {
165 *token_opt = Some(Token::from_content("break"));
166 }
167 token_opt.as_mut().unwrap()
168 }
169 LastStatement::Continue(token_opt) => {
170 if token_opt.is_none() {
171 *token_opt = Some(Token::from_content("continue"));
172 }
173 token_opt.as_mut().unwrap()
174 }
175 LastStatement::Return(return_stmt) => return_stmt.mutate_first_token(),
176 }
177 }
178
179 pub fn mutate_last_token(&mut self) -> &mut Token {
182 match self {
183 LastStatement::Break(token_opt) => {
184 if token_opt.is_none() {
185 *token_opt = Some(Token::from_content("break"));
186 }
187 token_opt.as_mut().unwrap()
188 }
189 LastStatement::Continue(token_opt) => {
190 if token_opt.is_none() {
191 *token_opt = Some(Token::from_content("continue"));
192 }
193 token_opt.as_mut().unwrap()
194 }
195 LastStatement::Return(return_stmt) => return_stmt.mutate_last_token(),
196 }
197 }
198}
199
200impl From<ReturnStatement> for LastStatement {
201 fn from(statement: ReturnStatement) -> Self {
202 Self::Return(statement)
203 }
204}
205
206#[cfg(test)]
207mod test {
208 use super::*;
209
210 #[test]
211 fn default_return_statement_is_empty() {
212 assert!(ReturnStatement::default().is_empty())
213 }
214}