1use std::str::FromStr;
2
3use crate::table::Iter;
4use crate::{Item, RawString, Table};
5
6#[derive(Debug, Clone)]
8pub struct Document<S> {
9 pub(crate) root: Item,
10 pub(crate) trailing: RawString,
12 pub(crate) raw: S,
13}
14
15impl Document<&'static str> {
16 pub fn new() -> Self {
18 Default::default()
19 }
20}
21
22#[cfg(feature = "parse")]
23impl<S: AsRef<str>> Document<S> {
24 pub fn parse(raw: S) -> Result<Self, crate::TomlError> {
26 let source = toml_parser::Source::new(raw.as_ref());
27 let mut sink = crate::error::TomlSink::<Option<_>>::new(source);
28 let doc = crate::parser::parse_document(source, &mut sink);
29 if let Some(err) = sink.into_inner() {
30 Err(err)
31 } else {
32 Ok(Self {
33 root: doc.root,
34 trailing: doc.trailing,
35 raw,
36 })
37 }
38 }
39}
40
41impl<S: AsRef<str>> Document<S> {
42 pub(crate) fn despan(&mut self) {
46 self.root.despan(self.raw.as_ref());
47 self.trailing.despan(self.raw.as_ref());
48 }
49}
50
51impl<S> Document<S> {
52 pub fn as_item(&self) -> &Item {
54 &self.root
55 }
56
57 pub fn into_item(self) -> Item {
59 self.root
60 }
61
62 pub fn as_table(&self) -> &Table {
64 self.root.as_table().expect("root should always be a table")
65 }
66
67 pub fn into_table(self) -> Table {
69 self.root
70 .into_table()
71 .expect("root should always be a table")
72 }
73
74 pub fn iter(&self) -> Iter<'_> {
76 self.as_table().iter()
77 }
78
79 pub fn trailing(&self) -> &RawString {
81 &self.trailing
82 }
83}
84
85impl<S: AsRef<str>> Document<S> {
86 pub fn raw(&self) -> &str {
88 self.raw.as_ref()
89 }
90}
91
92impl<S: AsRef<str>> Document<S> {
93 pub fn into_mut(mut self) -> DocumentMut {
95 self.despan();
96 DocumentMut {
97 root: self.root,
98 trailing: self.trailing,
99 }
100 }
101}
102
103impl Default for Document<&'static str> {
104 fn default() -> Self {
105 Self {
106 root: Item::Table(Table::with_pos(Some(0))),
107 trailing: Default::default(),
108 raw: "",
109 }
110 }
111}
112
113#[cfg(feature = "parse")]
114impl FromStr for Document<String> {
115 type Err = crate::TomlError;
116
117 fn from_str(s: &str) -> Result<Self, Self::Err> {
119 Self::parse(s.to_owned())
120 }
121}
122
123impl<S> std::ops::Deref for Document<S> {
124 type Target = Table;
125
126 fn deref(&self) -> &Self::Target {
127 self.as_table()
128 }
129}
130
131#[derive(Debug, Clone)]
133pub struct DocumentMut {
134 pub(crate) root: Item,
135 pub(crate) trailing: RawString,
137}
138
139impl DocumentMut {
140 pub fn new() -> Self {
142 Default::default()
143 }
144
145 pub fn as_item(&self) -> &Item {
147 &self.root
148 }
149
150 pub fn as_item_mut(&mut self) -> &mut Item {
152 &mut self.root
153 }
154
155 pub fn into_item(self) -> Item {
157 self.root
158 }
159
160 pub fn as_table(&self) -> &Table {
162 self.root.as_table().expect("root should always be a table")
163 }
164
165 pub fn as_table_mut(&mut self) -> &mut Table {
167 self.root
168 .as_table_mut()
169 .expect("root should always be a table")
170 }
171
172 pub fn into_table(self) -> Table {
174 self.root
175 .into_table()
176 .expect("root should always be a table")
177 }
178
179 pub fn iter(&self) -> Iter<'_> {
181 self.as_table().iter()
182 }
183
184 pub fn set_trailing(&mut self, trailing: impl Into<RawString>) {
186 self.trailing = trailing.into();
187 }
188
189 pub fn trailing(&self) -> &RawString {
191 &self.trailing
192 }
193}
194
195impl Default for DocumentMut {
196 fn default() -> Self {
197 Self {
198 root: Item::Table(Table::with_pos(Some(0))),
199 trailing: Default::default(),
200 }
201 }
202}
203
204#[cfg(feature = "parse")]
205impl FromStr for DocumentMut {
206 type Err = crate::TomlError;
207
208 fn from_str(s: &str) -> Result<Self, Self::Err> {
210 let im = Document::from_str(s)?;
211 Ok(im.into_mut())
212 }
213}
214
215impl std::ops::Deref for DocumentMut {
216 type Target = Table;
217
218 fn deref(&self) -> &Self::Target {
219 self.as_table()
220 }
221}
222
223impl std::ops::DerefMut for DocumentMut {
224 fn deref_mut(&mut self) -> &mut Self::Target {
225 self.as_table_mut()
226 }
227}
228
229impl From<Table> for DocumentMut {
230 fn from(root: Table) -> Self {
231 Self {
232 root: Item::Table(root),
233 ..Default::default()
234 }
235 }
236}
237
238#[test]
239#[cfg(feature = "parse")]
240#[cfg(feature = "display")]
241fn default_roundtrip() {
242 DocumentMut::default()
243 .to_string()
244 .parse::<DocumentMut>()
245 .unwrap();
246}