1use super::data::GroupKind;
2
3#[derive(Clone)]
5pub struct Printer {
6 buf: String,
7 prev: PrinterState,
8}
9
10#[derive(Clone, PartialEq, Eq)]
11pub enum PrinterState {
12 Group,
13 Text,
14}
15
16impl Default for Printer {
17 fn default() -> Self {
18 Self {
19 buf: String::new(),
20 prev: PrinterState::Group,
21 }
22 }
23}
24
25impl Printer {
26 pub fn open(&mut self, grp: GroupKind) {
28 if self.prev == PrinterState::Text {
29 self.buf.push(' ');
30 }
31 let c = match grp {
32 GroupKind::Paren => '(',
33 GroupKind::Bracket => '[',
34 GroupKind::Brace => '{',
35 };
36 self.prev = PrinterState::Group;
37 self.buf.push(c);
38 }
39
40 pub fn close(&mut self, grp: GroupKind) {
42 let c = match grp {
43 GroupKind::Paren => ')',
44 GroupKind::Bracket => ']',
45 GroupKind::Brace => '}',
46 };
47 self.prev = PrinterState::Group;
48 self.buf.push(c);
49 }
50
51 pub fn text(&mut self, s: &str) {
53 if self.prev == PrinterState::Text {
54 self.buf.push(' ');
55 }
56 self.prev = PrinterState::Text;
57 self.buf.push_str(s)
58 }
59
60 pub fn to_string(self) -> String {
61 self.buf
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn t1() {
71 let mut p = Printer::default();
72 p.open(GroupKind::Paren);
73 p.close(GroupKind::Paren);
74 let out = p.to_string();
75 assert_eq!(out, "()");
76 }
77
78 #[test]
79 fn t2() {
80 let mut p = Printer::default();
81 p.open(GroupKind::Paren);
82 p.text("let");
83 p.text("x");
84 p.text("=");
85 p.text("1");
86 p.close(GroupKind::Paren);
87 let out = p.to_string();
88 assert_eq!(out, "(let x = 1)");
89 }
90
91 #[test]
92 fn t3() {
93 let mut p = Printer::default();
94 p.open(GroupKind::Paren);
95 p.text("let");
96 p.text("x");
97 p.text("=");
98 p.open(GroupKind::Paren);
99 p.text("+");
100 p.text("1");
101 p.text("0xabc");
102 p.close(GroupKind::Paren);
103 p.close(GroupKind::Paren);
104 let out = p.to_string();
105 assert_eq!(out, "(let x = (+ 1 0xabc))");
106 }
107}