1use std::fmt;
2use std::default::Default;
3
4
5#[derive(Debug, PartialEq)]
6pub(crate) struct Formatter<'a> {
7 buf: String,
8 style: &'a Style,
9 indent: u32,
10}
11
12#[derive(Debug, PartialEq, Clone)]
17pub struct Style {
18 indent: u32,
19}
20
21impl Default for Style {
22 fn default() -> Style {
23 Style {
24 indent: 4,
25 }
26 }
27}
28
29impl Style {
30 pub fn indent(&mut self, indent: u32) -> &mut Self {
32 self.indent = indent;
33 self
34 }
35}
36
37pub(crate) trait Displayable {
38 fn display(&self, f: &mut Formatter);
39}
40
41impl<'a> Formatter<'a> {
42 pub fn new(style: &Style) -> Formatter {
43 Formatter {
44 buf: String::with_capacity(1024),
45 style,
46 indent: 0,
47 }
48 }
49
50 pub fn indent(&mut self) {
51 for _ in 0..self.indent {
52 self.buf.push(' ');
53 }
54 }
55
56 pub fn end(&mut self) {
57 self.buf.push(';');
58 self.buf.push('\n');
59 }
60 pub fn endline(&mut self) {
61 self.buf.push('\n');
62 }
63
64 pub fn start_block(&mut self) {
65 self.buf.push('{');
66 self.endline();
67 self.indent += self.style.indent;
68 }
69
70 pub fn end_block(&mut self) {
71 self.indent = self.indent.checked_sub(self.style.indent)
72 .expect("negative indent");
73 self.indent();
74 self.buf.push('}');
75 self.endline();
76 }
77
78 pub fn margin(&mut self) {
79 if !self.buf.is_empty() && !self.buf.ends_with("{\n") {
80 self.buf.push('\n');
81 }
82 }
83
84 pub fn write(&mut self, s: &str) {
85 self.buf.push_str(s);
86 }
87 pub fn fmt<D: fmt::Display>(&mut self, s: &D) {
88 use std::fmt::Write;
89 write!(&mut self.buf, "{}", s).expect("write never fails");
90 }
91
92 pub fn into_string(self) -> String {
93 self.buf
94 }
95}