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, 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}