1use std::fmt::{self, Write};
2
3use crate::body::Body;
4use crate::formatter::Formatter;
5
6#[derive(Debug, Clone)]
8pub struct Block {
9 before: Option<String>,
10 after: Option<String>,
11 body: Vec<Body>,
12}
13
14impl Block {
15 pub fn new(before: &str) -> Self {
17 Block {
18 before: Some(before.to_string()),
19 after: None,
20 body: vec![],
21 }
22 }
23
24 pub fn line<T>(&mut self, line: T) -> &mut Self
26 where
27 T: ToString,
28 {
29 self.body.push(Body::String(line.to_string()));
30 self
31 }
32
33 pub fn push_block(&mut self, block: Block) -> &mut Self {
35 self.body.push(Body::Block(block));
36 self
37 }
38
39 pub fn after(&mut self, after: &str) -> &mut Self {
41 self.after = Some(after.to_string());
42 self
43 }
44
45 pub fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
47 if let Some(ref before) = self.before {
48 write!(fmt, "{}", before)?;
49 }
50
51 if !fmt.is_start_of_line() {
54 write!(fmt, " ")?;
55 }
56
57 write!(fmt, "{{\n")?;
58
59 fmt.indent(|fmt| {
60 for b in &self.body {
61 b.fmt(fmt)?;
62 }
63
64 Ok(())
65 })?;
66
67 write!(fmt, "}}")?;
68
69 if let Some(ref after) = self.after {
70 write!(fmt, "{}", after)?;
71 }
72
73 write!(fmt, "\n")?;
74 Ok(())
75 }
76}