Skip to main content

code_gen/common/
block.rs

1use crate::{CodeBuffer, Statement, WithStatements};
2
3/// A block of statements.
4#[derive(Default)]
5pub struct Block {
6    statements: Vec<Box<dyn Statement>>,
7}
8
9impl From<Block> for Vec<Box<dyn Statement>> {
10    fn from(block: Block) -> Self {
11        block.statements
12    }
13}
14
15impl WithStatements for Block {
16    fn statements(&self) -> &[Box<dyn Statement>] {
17        self.statements.as_slice()
18    }
19
20    fn add_boxed_statement(&mut self, statement: Box<dyn Statement>) {
21        self.statements.push(statement);
22    }
23}
24
25impl Statement for Block {
26    fn write(&self, b: &mut CodeBuffer, level: usize) {
27        self.statements.iter().for_each(|s| s.write(b, level));
28    }
29}
30
31#[cfg(test)]
32mod tests {
33    use super::*;
34    use crate::WithStatements;
35
36    #[test]
37    fn empty_block() {
38        let block = Block::default();
39        assert_eq!(block.to_code(), "");
40    }
41
42    #[test]
43    fn block_with_statements() {
44        let mut block = Block::default();
45        block.add_semi("let a = 1");
46        block.add_semi("let b = 2");
47        assert_eq!(block.to_code(), "let a = 1;\nlet b = 2;\n");
48    }
49
50    #[test]
51    fn block_with_chaining() {
52        let block = Block::default()
53            .with_semi("let a = 1")
54            .with_semi("let b = 2");
55        assert_eq!(block.to_code(), "let a = 1;\nlet b = 2;\n");
56    }
57
58    #[test]
59    fn block_indented() {
60        let mut block = Block::default();
61        block.add_semi("x");
62        let mut b = CodeBuffer::default();
63        block.write(&mut b, 1);
64        assert_eq!(b.peek(), "    x;\n");
65    }
66
67    #[test]
68    fn block_into_vec() {
69        let mut block = Block::default();
70        block.add_semi("x");
71        let stmts: Vec<Box<dyn Statement>> = block.into();
72        assert_eq!(stmts.len(), 1);
73    }
74}