Skip to main content

toml/ser/document/
buffer.rs

1use toml_writer::TomlWrite as _;
2
3use crate::alloc_prelude::*;
4
5/// TOML Document serialization buffer
6#[derive(Debug, Default)]
7pub struct Buffer {
8    tables: Vec<Option<Table>>,
9}
10
11impl Buffer {
12    /// Initialize a new serialization buffer
13    pub fn new() -> Self {
14        Default::default()
15    }
16
17    /// Reset the buffer for serializing another document
18    pub fn clear(&mut self) {
19        self.tables.clear();
20    }
21
22    pub(crate) fn root_table(&mut self) -> Table {
23        self.new_table(None)
24    }
25
26    pub(crate) fn child_table(&mut self, parent: &mut Table, encoded_key: String) -> Table {
27        parent.has_children = true;
28        let mut encoded_key_path = parent.encoded_key.clone();
29        encoded_key_path
30            .get_or_insert_with(Vec::new)
31            .push(encoded_key);
32        self.new_table(encoded_key_path)
33    }
34
35    pub(crate) fn element_table(&mut self, parent: &mut Table, encoded_key: String) -> Table {
36        let mut table = self.child_table(parent, encoded_key);
37        table.array = true;
38        table
39    }
40
41    pub(crate) fn new_table(&mut self, encoded_key: Option<Vec<String>>) -> Table {
42        let pos = self.tables.len();
43        let table = Table {
44            encoded_key,
45            body: String::new(),
46            has_children: false,
47            pos,
48            array: false,
49        };
50        self.tables.push(None);
51        table
52    }
53
54    pub(crate) fn push(&mut self, table: Table) {
55        let pos = table.pos;
56        self.tables[pos] = Some(table);
57    }
58}
59
60impl core::fmt::Display for Buffer {
61    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
62        let mut tables = self
63            .tables
64            .iter()
65            .filter_map(|t| t.as_ref())
66            .filter(|t| required_table(t));
67        if let Some(table) = tables.next() {
68            table.fmt(f)?;
69        }
70        for table in tables {
71            f.newline()?;
72            table.fmt(f)?;
73        }
74        Ok(())
75    }
76}
77
78fn required_table(table: &Table) -> bool {
79    if table.encoded_key.is_none() {
80        !table.body.is_empty()
81    } else {
82        table.array || !table.body.is_empty() || !table.has_children
83    }
84}
85
86#[derive(Clone, Debug)]
87pub(crate) struct Table {
88    encoded_key: Option<Vec<String>>,
89    body: String,
90    has_children: bool,
91    array: bool,
92    pos: usize,
93}
94
95impl Table {
96    pub(crate) fn body_mut(&mut self) -> &mut String {
97        &mut self.body
98    }
99
100    pub(crate) fn has_children(&mut self, yes: bool) {
101        self.has_children = yes;
102    }
103}
104
105impl core::fmt::Display for Table {
106    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
107        if let Some(encoded_key) = &self.encoded_key {
108            if self.array {
109                f.open_array_of_tables_header()?;
110            } else {
111                f.open_table_header()?;
112            }
113            let mut encoded_keys = encoded_key.iter();
114            if let Some(encoded_key) = encoded_keys.next() {
115                write!(f, "{encoded_key}")?;
116            }
117            for encoded_key in encoded_keys {
118                f.key_sep()?;
119                write!(f, "{encoded_key}")?;
120            }
121            if self.array {
122                f.close_array_of_tables_header()?;
123            } else {
124                f.close_table_header()?;
125            }
126            f.newline()?;
127        }
128
129        self.body.fmt(f)?;
130
131        Ok(())
132    }
133}