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 CodeBuffer {
42    //! Deconstruction
43
44    /// Exports the buffered code.
45    pub fn export(self) -> String {
46        self.code
47    }
48}
49
50impl From<CodeBuffer> for String {
51    fn from(code_buffer: CodeBuffer) -> Self {
52        code_buffer.export()
53    }
54}
55
56impl Default for CodeBuffer {
57    fn default() -> Self {
58        Self::new(
59            Self::DEFAULT_INDENT,
60            Self::DEFAULT_LINE_ENDING,
61            Self::DEFAULT_CAPACITY,
62        )
63    }
64}
65
66impl CodeBuffer {
67    //! Writing
68
69    /// Writes the code.
70    pub fn write(&mut self, code: &str) {
71        self.code.push_str(code);
72    }
73
74    /// Writes the indent level.
75    pub fn indent(&mut self, level: usize) {
76        for _ in 0..level {
77            self.code.push_str(self.indent.as_mut_str());
78        }
79    }
80
81    /// Writes a line-ending.
82    pub fn end_line(&mut self) {
83        self.code.push_str(self.line_ending.as_str());
84    }
85
86    /// Writes a line of code at the indent level with a line-ending.
87    pub fn line(&mut self, level: usize, code: &str) {
88        self.indent(level);
89        self.write(code);
90        self.end_line();
91    }
92
93    /// Writes a single space.
94    pub fn space(&mut self) {
95        self.code.push_str(" ");
96    }
97}
98
99impl CodeBuffer {
100    //! Access
101
102    /// Peeks at the buffered code.
103    pub fn peek(&self) -> &str {
104        self.code.as_str()
105    }
106
107    /// Clears the buffered code.
108    pub fn clear(&mut self) {
109        self.code.clear();
110    }
111}
112
113impl Display for CodeBuffer {
114    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
115        write!(f, "{}", self.peek())
116    }
117}