code_gen/common/
code_buffer.rs

1use std::fmt::{Display, Formatter};
2
3/// Responsible for buffering code.
4#[derive(Clone, Debug)]
5pub struct CodeBuffer {
6    indent: String,
7    line_ending: String,
8    code: String,
9}
10
11impl CodeBuffer {
12    //! Constants
13
14    /// The default indent. (4 spaces)
15    pub const DEFAULT_INDENT: &'static str = "    ";
16
17    /// The default line-ending.
18    pub const DEFAULT_LINE_ENDING: &'static str = "\n";
19
20    /// The default buffer capacity. (4 KiB)
21    pub const DEFAULT_CAPACITY: usize = 4 * 1024;
22}
23
24impl CodeBuffer {
25    //! Construction
26
27    /// Creates a new code buffer.
28    pub fn new<S0, S1>(indent: S0, line_ending: S1, capacity: usize) -> Self
29    where
30        S0: Into<String>,
31        S1: Into<String>,
32    {
33        Self {
34            indent: indent.into(),
35            line_ending: line_ending.into(),
36            code: String::with_capacity(capacity),
37        }
38    }
39}
40
41impl Default for CodeBuffer {
42    fn default() -> Self {
43        Self::new(
44            Self::DEFAULT_INDENT,
45            Self::DEFAULT_LINE_ENDING,
46            Self::DEFAULT_CAPACITY,
47        )
48    }
49}
50
51impl From<CodeBuffer> for String {
52    fn from(buffer: CodeBuffer) -> Self {
53        buffer.code
54    }
55}
56
57impl CodeBuffer {
58    //! Access
59
60    /// Peeks at the buffered code.
61    pub fn peek(&self) -> &str {
62        self.code.as_str()
63    }
64
65    /// Clears the buffered code.
66    pub fn clear(&mut self) {
67        self.code.clear();
68    }
69}
70
71impl CodeBuffer {
72    //! Writing
73
74    /// Writes the `code`.
75    pub fn write(&mut self, code: &str) {
76        self.code.push_str(code);
77    }
78
79    /// Writes the indent `level`.
80    pub fn indent(&mut self, level: usize) {
81        for _ in 0..level {
82            self.code.push_str(self.indent.as_mut_str());
83        }
84    }
85
86    /// Writes a line-ending.
87    pub fn end_line(&mut self) {
88        self.code.push_str(self.line_ending.as_str());
89    }
90
91    /// Writes a line of `code` at the indent `level` with a line-ending.
92    pub fn line(&mut self, level: usize, code: &str) {
93        self.indent(level);
94        self.write(code);
95        self.end_line();
96    }
97
98    /// Writes a single space.
99    pub fn space(&mut self) {
100        self.code.push(' ');
101    }
102}
103
104impl Display for CodeBuffer {
105    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
106        write!(f, "{}", self.peek())
107    }
108}