1use std::io::{prelude::*, BufReader, BufWriter};
2
3pub struct Formatter<R: Read, W: Write> {
4 reader: BufReader<R>,
5 writer: BufWriter<W>,
6 current: u8,
7 previous: u8,
8 newline: String,
9 indent: String,
10 levels: Vec<Level>,
11}
12
13#[derive(Clone)]
14struct Level {
15 break_newline: bool,
16}
17
18impl<R: Read, W: Write> Formatter<R, W> {
19 pub fn new(reader: R, writer: W) -> Self {
20 Self {
21 reader: BufReader::new(reader),
22 writer: BufWriter::new(writer),
23 current: 0,
24 previous: 0,
25 newline: "\n".to_string(),
26 indent: " ".to_string(),
27 levels: Vec::with_capacity(10),
28 }
29 }
30
31 pub fn format(mut self) -> std::io::Result<()> {
32 while self.read_next() {
33 self.update();
34 self.write()?;
35 }
36 Ok(())
37 }
38}
39
40impl<R: Read, W: Write> Formatter<R, W> {
42 fn push_level(&mut self, level: Level) {
43 self.levels.push(level);
44 }
45
46 fn pop_level(&mut self) {
47 if !self.levels.is_empty() {
48 self.levels.pop();
49 }
50 }
51
52 fn current_level(&self) -> Level {
53 self.levels.last().cloned().unwrap_or(Level {
54 break_newline: false,
55 })
56 }
57
58 fn indent_level(&self) -> i32 {
59 self.levels.len() as _
60 }
61
62 fn read_next(&mut self) -> bool {
63 self.previous = self.current;
64 let buf = std::slice::from_mut(&mut self.current);
65 self.reader.read_exact(buf).is_ok()
66 }
67
68 fn update(&mut self) {
69 self.update_level();
70 }
71
72 fn update_level(&mut self) {
73 match self.previous {
74 b'}' | b')' if self.indent_level() > 0 => self.pop_level(),
75 _ => {}
76 };
77 match self.current {
78 b'{' => self.push_level(Level {
79 break_newline: true,
80 }),
81 b'(' => self.push_level(Level {
82 break_newline: false,
83 }),
84 _ => {}
85 };
86 }
87
88 fn write(&mut self) -> std::io::Result<()> {
89 match self.previous {
90 b'{' | b'(' | b',' => {
91 if self.current_level().break_newline {
92 self.write_newline()?;
93 self.write_indent(self.indent_level())?;
94 }
95 }
96 _ => {}
97 };
98
99 match self.current {
100 b'}' | b')' => {
101 if self.current_level().break_newline {
102 self.write_newline()?;
103 self.write_indent(self.indent_level() - 1)?;
104 }
105 }
106 _ => {}
107 };
108
109 let current = std::slice::from_ref(&self.current);
110 self.writer.write_all(current).unwrap();
111
112 Ok(())
113 }
114
115 fn write_newline(&mut self) -> std::io::Result<()> {
116 self.writer.write_all(self.newline.as_bytes())
117 }
118
119 fn write_indent(&mut self, n: i32) -> std::io::Result<()> {
120 let buf = self.indent.as_bytes();
121 for _ in 0..n {
122 self.writer.write_all(buf)?;
123 }
124 Ok(())
125 }
126}