1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
use crate::lua_generator::{LuaGenerator, ToLua}; use crate::nodes::{LastStatement, Statement}; #[derive(Clone, Debug, PartialEq, Eq)] pub struct Block { statements: Vec<Statement>, last_statement: Option<LastStatement>, } impl Block { pub fn new(statements: Vec<Statement>, last_statement: Option<LastStatement>) -> Self { Self { statements, last_statement, } } pub fn with_statement<T: Into<Statement>>(mut self, statement: T) -> Self { self.statements.push(statement.into()); self } pub fn with_last_statement(mut self, last_statement: LastStatement) -> Self { self.last_statement = Some(last_statement); self } pub fn is_empty(&self) -> bool { self.last_statement.is_none() && self.statements.is_empty() } pub fn get_statements(&self) -> &Vec<Statement> { &self.statements } pub fn filter_statements<F>(&mut self, mut f: F) where F: FnMut(&mut Statement) -> bool { let mut i = 0; while i != self.statements.len() { if f(&mut self.statements[i]) { i += 1; } else { self.statements.remove(i); } } } pub fn mutate_statements(&mut self) -> &mut Vec<Statement> { &mut self.statements } pub fn mutate_last_statement(&mut self) -> &mut Option<LastStatement> { &mut self.last_statement } pub fn clear(&mut self) { self.statements.clear(); self.last_statement.take(); } } impl Default for Block { fn default() -> Self { Self::new(Vec::new(), None) } } impl ToLua for Block { fn to_lua(&self, generator: &mut LuaGenerator) { generator.for_each_and_between( &self.statements, |generator, statement| statement.to_lua(generator), |generator| generator.push_char(';'), ); if let Some(last_statement) = &self.last_statement { if self.statements.len() > 0 { generator.push_char(';'); }; last_statement.to_lua(generator); generator.push_char(';'); } } } #[cfg(test)] mod test { use super::*; use crate::nodes::DoStatement; #[test] fn default_block_is_empty() { let block = Block::default(); assert!(block.is_empty()); } #[test] fn is_empty_is_true_when_block_has_no_statements_or_last_statement() { let block = Block::new(Vec::new(), None); assert!(block.is_empty()); } #[test] fn is_empty_is_false_when_block_has_a_last_statement() { let block = Block::default().with_last_statement(LastStatement::Break); assert!(!block.is_empty()); } #[test] fn is_empty_is_false_when_block_a_statement() { let block = Block::default().with_statement(DoStatement::default()); assert!(!block.is_empty()); } #[test] fn clear_removes_statements() { let mut block = Block::default().with_statement(DoStatement::default()); block.clear(); assert!(block.is_empty()); } #[test] fn clear_removes_last_statement() { let mut block = Block::default().with_last_statement(LastStatement::Break); block.clear(); assert!(block.is_empty()); } }