1use std::str::FromStr;
2
3use crate::table::Iter;
4use crate::{Item, RawString, Table};
5
6#[derive(Debug, Clone)]
8pub struct ImDocument<S> {
9 pub(crate) root: Item,
10 pub(crate) trailing: RawString,
12 pub(crate) raw: S,
13}
14
15impl ImDocument<&'static str> {
16 pub fn new() -> Self {
18 Default::default()
19 }
20}
21
22#[cfg(feature = "parse")]
23impl<S: AsRef<str>> ImDocument<S> {
24 pub fn parse(raw: S) -> Result<Self, crate::TomlError> {
26 crate::parser::parse_document(raw)
27 }
28}
29
30impl<S: AsRef<str>> ImDocument<S> {
31 pub(crate) fn despan(&mut self) {
35 self.root.despan(self.raw.as_ref());
36 self.trailing.despan(self.raw.as_ref());
37 }
38}
39
40impl<S> ImDocument<S> {
41 pub fn as_item(&self) -> &Item {
43 &self.root
44 }
45
46 pub fn as_table(&self) -> &Table {
48 self.root.as_table().expect("root should always be a table")
49 }
50
51 pub fn iter(&self) -> Iter<'_> {
53 self.as_table().iter()
54 }
55
56 pub fn trailing(&self) -> &RawString {
58 &self.trailing
59 }
60}
61
62impl<S: AsRef<str>> ImDocument<S> {
63 pub fn raw(&self) -> &str {
65 self.raw.as_ref()
66 }
67}
68
69impl<S: AsRef<str>> ImDocument<S> {
70 pub fn into_mut(mut self) -> DocumentMut {
72 self.despan();
73 DocumentMut {
74 root: self.root,
75 trailing: self.trailing,
76 }
77 }
78}
79
80impl Default for ImDocument<&'static str> {
81 fn default() -> Self {
82 Self {
83 root: Item::Table(Table::with_pos(Some(0))),
84 trailing: Default::default(),
85 raw: "",
86 }
87 }
88}
89
90#[cfg(feature = "parse")]
91impl FromStr for ImDocument<String> {
92 type Err = crate::TomlError;
93
94 fn from_str(s: &str) -> Result<Self, Self::Err> {
96 Self::parse(s.to_owned())
97 }
98}
99
100impl<S> std::ops::Deref for ImDocument<S> {
101 type Target = Table;
102
103 fn deref(&self) -> &Self::Target {
104 self.as_table()
105 }
106}
107
108#[derive(Debug, Clone)]
110pub struct DocumentMut {
111 pub(crate) root: Item,
112 pub(crate) trailing: RawString,
114}
115
116impl DocumentMut {
117 pub fn new() -> Self {
119 Default::default()
120 }
121
122 pub fn as_item(&self) -> &Item {
124 &self.root
125 }
126
127 pub fn as_item_mut(&mut self) -> &mut Item {
129 &mut self.root
130 }
131
132 pub fn as_table(&self) -> &Table {
134 self.root.as_table().expect("root should always be a table")
135 }
136
137 pub fn as_table_mut(&mut self) -> &mut Table {
139 self.root
140 .as_table_mut()
141 .expect("root should always be a table")
142 }
143
144 pub fn iter(&self) -> Iter<'_> {
146 self.as_table().iter()
147 }
148
149 pub fn set_trailing(&mut self, trailing: impl Into<RawString>) {
151 self.trailing = trailing.into();
152 }
153
154 pub fn trailing(&self) -> &RawString {
156 &self.trailing
157 }
158}
159
160impl Default for DocumentMut {
161 fn default() -> Self {
162 Self {
163 root: Item::Table(Table::with_pos(Some(0))),
164 trailing: Default::default(),
165 }
166 }
167}
168
169#[cfg(feature = "parse")]
170impl FromStr for DocumentMut {
171 type Err = crate::TomlError;
172
173 fn from_str(s: &str) -> Result<Self, Self::Err> {
175 let im = ImDocument::from_str(s)?;
176 Ok(im.into_mut())
177 }
178}
179
180impl std::ops::Deref for DocumentMut {
181 type Target = Table;
182
183 fn deref(&self) -> &Self::Target {
184 self.as_table()
185 }
186}
187
188impl std::ops::DerefMut for DocumentMut {
189 fn deref_mut(&mut self) -> &mut Self::Target {
190 self.as_table_mut()
191 }
192}
193
194impl From<Table> for DocumentMut {
195 fn from(root: Table) -> Self {
196 Self {
197 root: Item::Table(root),
198 ..Default::default()
199 }
200 }
201}
202
203#[test]
204#[cfg(feature = "parse")]
205#[cfg(feature = "display")]
206fn default_roundtrip() {
207 DocumentMut::default()
208 .to_string()
209 .parse::<DocumentMut>()
210 .unwrap();
211}