Skip to main content

oak_core/source/
buffer.rs

1//! Source buffer for code generation and minification.
2
3/// A trait for types that can be converted to source code.
4pub trait ToSource {
5    /// Writes the source code representation of this type to the provided buffer.
6    fn to_source(&self, buffer: &mut SourceBuffer);
7
8    /// Converts this type to a source code string.
9    fn to_source_string(&self) -> String {
10        let mut buffer = SourceBuffer::new();
11        self.to_source(&mut buffer);
12        buffer.finish()
13    }
14}
15
16/// A buffer for building source code with intelligent spacing for minification.
17#[derive(Debug, Clone, Default)]
18pub struct SourceBuffer {
19    inner: String,
20    last_char: Option<char>,
21}
22
23impl SourceBuffer {
24    /// Creates a new, empty source buffer.
25    pub fn new() -> Self {
26        Self::default()
27    }
28
29    /// Pushes a string to the buffer, automatically adding a space if necessary to prevent token merging.
30    pub fn push(&mut self, s: &str) {
31        if let Some(first) = s.chars().next() {
32            // If both the last character and the first character of the new string are "word" characters,
33            // we must insert a space to prevent them from merging into a single token (e.g., "let" + "a" -> "let a").
34            if self.is_word_char(self.last_char) && self.is_word_char(Some(first)) {
35                self.inner.push(' ');
36            }
37            self.inner.push_str(s);
38            self.last_char = s.chars().last();
39        }
40    }
41
42    /// Returns the accumulated source code as a string.
43    pub fn finish(self) -> String {
44        self.inner
45    }
46
47    /// Helper to check if a character is a "word" character (alphanumeric or underscore).
48    fn is_word_char(&self, c: Option<char>) -> bool {
49        c.map_or(false, |c| c.is_alphanumeric() || c == '_')
50    }
51}
52
53impl From<SourceBuffer> for String {
54    fn from(buffer: SourceBuffer) -> Self {
55        buffer.finish()
56    }
57}