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