oak_core/source/
buffer.rs1pub trait ToSource {
5 fn to_source(&self, buffer: &mut SourceBuffer);
7
8 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#[derive(Debug, Clone, Default)]
18pub struct SourceBuffer {
19 inner: String,
20 last_char: Option<char>,
21}
22
23impl std::fmt::Display for SourceBuffer {
24 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 write!(f, "{}", self.inner)
26 }
27}
28
29impl SourceBuffer {
30 pub fn new() -> Self {
32 Self::default()
33 }
34
35 pub fn push(&mut self, s: &str) {
37 if let Some(first) = s.chars().next() {
38 if self.is_word_char(self.last_char) && self.is_word_char(Some(first)) {
41 self.inner.push(' ')
42 }
43 self.inner.push_str(s);
44 self.last_char = s.chars().last()
45 }
46 }
47
48 pub fn push_char(&mut self, c: char) {
50 if self.is_word_char(self.last_char) && self.is_word_char(Some(c)) {
51 self.inner.push(' ')
52 }
53 self.inner.push(c);
54 self.last_char = Some(c);
55 }
56
57 pub fn finish(self) -> String {
59 self.inner
60 }
61
62 fn is_word_char(&self, c: Option<char>) -> bool {
64 c.map_or(false, |c| c.is_alphanumeric() || c == '_')
65 }
66}
67
68impl From<SourceBuffer> for String {
69 fn from(buffer: SourceBuffer) -> Self {
70 buffer.finish()
71 }
72}