/rust/registry/src/index.crates.io-6f17d22bba15001f/toml-0.5.11/src/macros.rs
Line | Count | Source (jump to first uncovered line) |
1 | | pub use serde::de::{Deserialize, IntoDeserializer}; |
2 | | |
3 | | use crate::value::{Array, Table, Value}; |
4 | | |
5 | | /// Construct a [`toml::Value`] from TOML syntax. |
6 | | /// |
7 | | /// [`toml::Value`]: value/enum.Value.html |
8 | | /// |
9 | | /// ```rust |
10 | | /// let cargo_toml = toml::toml! { |
11 | | /// [package] |
12 | | /// name = "toml" |
13 | | /// version = "0.4.5" |
14 | | /// authors = ["Alex Crichton <alex@alexcrichton.com>"] |
15 | | /// |
16 | | /// [badges] |
17 | | /// travis-ci = { repository = "alexcrichton/toml-rs" } |
18 | | /// |
19 | | /// [dependencies] |
20 | | /// serde = "1.0" |
21 | | /// |
22 | | /// [dev-dependencies] |
23 | | /// serde_derive = "1.0" |
24 | | /// serde_json = "1.0" |
25 | | /// }; |
26 | | /// |
27 | | /// println!("{:#?}", cargo_toml); |
28 | | /// ``` |
29 | | #[macro_export] |
30 | | macro_rules! toml { |
31 | | ($($toml:tt)+) => {{ |
32 | | let table = $crate::value::Table::new(); |
33 | | let mut root = $crate::Value::Table(table); |
34 | | $crate::toml_internal!(@toplevel root [] $($toml)+); |
35 | | root |
36 | | }}; |
37 | | } |
38 | | |
39 | | // TT-muncher to parse TOML syntax into a toml::Value. |
40 | | // |
41 | | // @toplevel -- Parse tokens outside of an inline table or inline array. In |
42 | | // this state, `[table headers]` and `[[array headers]]` are |
43 | | // allowed and `key = value` pairs are not separated by commas. |
44 | | // |
45 | | // @topleveldatetime -- Helper to parse a Datetime from string and insert it |
46 | | // into a table, continuing in the @toplevel state. |
47 | | // |
48 | | // @path -- Turn a path segment into a string. Segments that look like idents |
49 | | // are stringified, while quoted segments like `"cfg(windows)"` |
50 | | // are not. |
51 | | // |
52 | | // @value -- Parse the value part of a `key = value` pair, which may be a |
53 | | // primitive or inline table or inline array. |
54 | | // |
55 | | // @table -- Parse the contents of an inline table, returning them as a |
56 | | // toml::Value::Table. |
57 | | // |
58 | | // @tabledatetime -- Helper to parse a Datetime from string and insert it |
59 | | // into a table, continuing in the @table state. |
60 | | // |
61 | | // @array -- Parse the contents of an inline array, returning them as a |
62 | | // toml::Value::Array. |
63 | | // |
64 | | // @arraydatetime -- Helper to parse a Datetime from string and push it into |
65 | | // an array, continuing in the @array state. |
66 | | // |
67 | | // @trailingcomma -- Helper to append a comma to a sequence of tokens if the |
68 | | // sequence is non-empty and does not already end in a trailing |
69 | | // comma. |
70 | | // |
71 | | #[macro_export] |
72 | | #[doc(hidden)] |
73 | | macro_rules! toml_internal { |
74 | | // Base case, no elements remaining. |
75 | | (@toplevel $root:ident [$($path:tt)*]) => {}; |
76 | | |
77 | | // Parse negative number `key = -value`. |
78 | | (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = - $v:tt $($rest:tt)*) => { |
79 | | $crate::toml_internal!(@toplevel $root [$($path)*] $($($k)-+).+ = (-$v) $($rest)*); |
80 | | }; |
81 | | |
82 | | // Parse positive number `key = +value`. |
83 | | (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = + $v:tt $($rest:tt)*) => { |
84 | | $crate::toml_internal!(@toplevel $root [$($path)*] $($($k)-+).+ = ($v) $($rest)*); |
85 | | }; |
86 | | |
87 | | // Parse offset datetime `key = 1979-05-27T00:32:00.999999-07:00`. |
88 | | (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt $($rest:tt)*) => { |
89 | | $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec . $frac - $tzh : $tzm) $($rest)*); |
90 | | }; |
91 | | // Space instead of T. |
92 | | (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt $($rest:tt)*) => { |
93 | | $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec . $frac - $tzh : $tzm) $($rest)*); |
94 | | }; |
95 | | |
96 | | // Parse offset datetime `key = 1979-05-27T00:32:00-07:00`. |
97 | | (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt $($rest:tt)*) => { |
98 | | $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec - $tzh : $tzm) $($rest)*); |
99 | | }; |
100 | | // Space instead of T. |
101 | | (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt $($rest:tt)*) => { |
102 | | $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec - $tzh : $tzm) $($rest)*); |
103 | | }; |
104 | | |
105 | | // Parse local datetime `key = 1979-05-27T00:32:00.999999`. |
106 | | (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt $($rest:tt)*) => { |
107 | | $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec . $frac) $($rest)*); |
108 | | }; |
109 | | // Space instead of T. |
110 | | (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt $($rest:tt)*) => { |
111 | | $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec . $frac) $($rest)*); |
112 | | }; |
113 | | |
114 | | // Parse offset datetime `key = 1979-05-27T07:32:00Z` and local datetime `key = 1979-05-27T07:32:00`. |
115 | | (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt $($rest:tt)*) => { |
116 | | $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec) $($rest)*); |
117 | | }; |
118 | | // Space instead of T. |
119 | | (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt $($rest:tt)*) => { |
120 | | $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec) $($rest)*); |
121 | | }; |
122 | | |
123 | | // Parse local date `key = 1979-05-27`. |
124 | | (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $($rest:tt)*) => { |
125 | | $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day) $($rest)*); |
126 | | }; |
127 | | |
128 | | // Parse local time `key = 00:32:00.999999`. |
129 | | (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $hr:tt : $min:tt : $sec:tt . $frac:tt $($rest:tt)*) => { |
130 | | $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($hr : $min : $sec . $frac) $($rest)*); |
131 | | }; |
132 | | |
133 | | // Parse local time `key = 07:32:00`. |
134 | | (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $hr:tt : $min:tt : $sec:tt $($rest:tt)*) => { |
135 | | $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($hr : $min : $sec) $($rest)*); |
136 | | }; |
137 | | |
138 | | // Parse any other `key = value` including string, inline array, inline |
139 | | // table, number, and boolean. |
140 | | (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $v:tt $($rest:tt)*) => {{ |
141 | | $crate::macros::insert_toml( |
142 | | &mut $root, |
143 | | &[$($path)* $(&concat!($("-", $crate::toml_internal!(@path $k),)+)[1..], )+], |
144 | | $crate::toml_internal!(@value $v)); |
145 | | $crate::toml_internal!(@toplevel $root [$($path)*] $($rest)*); |
146 | | }}; |
147 | | |
148 | | // Parse array header `[[bin]]`. |
149 | | (@toplevel $root:ident $oldpath:tt [[$($($path:tt)-+).+]] $($rest:tt)*) => { |
150 | | $crate::macros::push_toml( |
151 | | &mut $root, |
152 | | &[$(&concat!($("-", $crate::toml_internal!(@path $path),)+)[1..],)+]); |
153 | | $crate::toml_internal!(@toplevel $root [$(&concat!($("-", $crate::toml_internal!(@path $path),)+)[1..],)+] $($rest)*); |
154 | | }; |
155 | | |
156 | | // Parse table header `[patch.crates-io]`. |
157 | | (@toplevel $root:ident $oldpath:tt [$($($path:tt)-+).+] $($rest:tt)*) => { |
158 | | $crate::macros::insert_toml( |
159 | | &mut $root, |
160 | | &[$(&concat!($("-", $crate::toml_internal!(@path $path),)+)[1..],)+], |
161 | | $crate::Value::Table($crate::value::Table::new())); |
162 | | $crate::toml_internal!(@toplevel $root [$(&concat!($("-", $crate::toml_internal!(@path $path),)+)[1..],)+] $($rest)*); |
163 | | }; |
164 | | |
165 | | // Parse datetime from string and insert into table. |
166 | | (@topleveldatetime $root:ident [$($path:tt)*] $($($k:tt)-+).+ = ($($datetime:tt)+) $($rest:tt)*) => { |
167 | | $crate::macros::insert_toml( |
168 | | &mut $root, |
169 | | &[$($path)* $(&concat!($("-", $crate::toml_internal!(@path $k),)+)[1..], )+], |
170 | | $crate::Value::Datetime(concat!($(stringify!($datetime)),+).parse().unwrap())); |
171 | | $crate::toml_internal!(@toplevel $root [$($path)*] $($rest)*); |
172 | | }; |
173 | | |
174 | | // Turn a path segment into a string. |
175 | | (@path $ident:ident) => { |
176 | | stringify!($ident) |
177 | | }; |
178 | | |
179 | | // For a path segment that is not an ident, expect that it is already a |
180 | | // quoted string, like in `[target."cfg(windows)".dependencies]`. |
181 | | (@path $quoted:tt) => { |
182 | | $quoted |
183 | | }; |
184 | | |
185 | | // Construct a Value from an inline table. |
186 | | (@value { $($inline:tt)* }) => {{ |
187 | | let mut table = $crate::Value::Table($crate::value::Table::new()); |
188 | | $crate::toml_internal!(@trailingcomma (@table table) $($inline)*); |
189 | | table |
190 | | }}; |
191 | | |
192 | | // Construct a Value from an inline array. |
193 | | (@value [ $($inline:tt)* ]) => {{ |
194 | | let mut array = $crate::value::Array::new(); |
195 | | $crate::toml_internal!(@trailingcomma (@array array) $($inline)*); |
196 | | $crate::Value::Array(array) |
197 | | }}; |
198 | | |
199 | | (@value (-nan)) => { |
200 | | $crate::Value::Float(-::std::f64::NAN) |
201 | | }; |
202 | | |
203 | | (@value (nan)) => { |
204 | | $crate::Value::Float(::std::f64::NAN) |
205 | | }; |
206 | | |
207 | | (@value nan) => { |
208 | | $crate::Value::Float(::std::f64::NAN) |
209 | | }; |
210 | | |
211 | | (@value (-inf)) => { |
212 | | $crate::Value::Float(::std::f64::NEG_INFINITY) |
213 | | }; |
214 | | |
215 | | (@value (inf)) => { |
216 | | $crate::Value::Float(::std::f64::INFINITY) |
217 | | }; |
218 | | |
219 | | (@value inf) => { |
220 | | $crate::Value::Float(::std::f64::INFINITY) |
221 | | }; |
222 | | |
223 | | // Construct a Value from any other type, probably string or boolean or number. |
224 | | (@value $v:tt) => {{ |
225 | | // TODO: Implement this with something like serde_json::to_value instead. |
226 | | let de = $crate::macros::IntoDeserializer::<$crate::de::Error>::into_deserializer($v); |
227 | | <$crate::Value as $crate::macros::Deserialize>::deserialize(de).unwrap() |
228 | | }}; |
229 | | |
230 | | // Base case of inline table. |
231 | | (@table $root:ident) => {}; |
232 | | |
233 | | // Parse negative number `key = -value`. |
234 | | (@table $root:ident $($($k:tt)-+).+ = - $v:tt , $($rest:tt)*) => { |
235 | | $crate::toml_internal!(@table $root $($($k)-+).+ = (-$v) , $($rest)*); |
236 | | }; |
237 | | |
238 | | // Parse positive number `key = +value`. |
239 | | (@table $root:ident $($($k:tt)-+).+ = + $v:tt , $($rest:tt)*) => { |
240 | | $crate::toml_internal!(@table $root $($($k)-+).+ = ($v) , $($rest)*); |
241 | | }; |
242 | | |
243 | | // Parse offset datetime `key = 1979-05-27T00:32:00.999999-07:00`. |
244 | | (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => { |
245 | | $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec . $frac - $tzh : $tzm) $($rest)*); |
246 | | }; |
247 | | // Space instead of T. |
248 | | (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => { |
249 | | $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec . $frac - $tzh : $tzm) $($rest)*); |
250 | | }; |
251 | | |
252 | | // Parse offset datetime `key = 1979-05-27T00:32:00-07:00`. |
253 | | (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => { |
254 | | $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec - $tzh : $tzm) $($rest)*); |
255 | | }; |
256 | | // Space instead of T. |
257 | | (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => { |
258 | | $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec - $tzh : $tzm) $($rest)*); |
259 | | }; |
260 | | |
261 | | // Parse local datetime `key = 1979-05-27T00:32:00.999999`. |
262 | | (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => { |
263 | | $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec . $frac) $($rest)*); |
264 | | }; |
265 | | // Space instead of T. |
266 | | (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => { |
267 | | $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec . $frac) $($rest)*); |
268 | | }; |
269 | | |
270 | | // Parse offset datetime `key = 1979-05-27T07:32:00Z` and local datetime `key = 1979-05-27T07:32:00`. |
271 | | (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt , $($rest:tt)*) => { |
272 | | $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec) $($rest)*); |
273 | | }; |
274 | | // Space instead of T. |
275 | | (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt , $($rest:tt)*) => { |
276 | | $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec) $($rest)*); |
277 | | }; |
278 | | |
279 | | // Parse local date `key = 1979-05-27`. |
280 | | (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt , $($rest:tt)*) => { |
281 | | $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day) $($rest)*); |
282 | | }; |
283 | | |
284 | | // Parse local time `key = 00:32:00.999999`. |
285 | | (@table $root:ident $($($k:tt)-+).+ = $hr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => { |
286 | | $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($hr : $min : $sec . $frac) $($rest)*); |
287 | | }; |
288 | | |
289 | | // Parse local time `key = 07:32:00`. |
290 | | (@table $root:ident $($($k:tt)-+).+ = $hr:tt : $min:tt : $sec:tt , $($rest:tt)*) => { |
291 | | $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($hr : $min : $sec) $($rest)*); |
292 | | }; |
293 | | |
294 | | // Parse any other type, probably string or boolean or number. |
295 | | (@table $root:ident $($($k:tt)-+).+ = $v:tt , $($rest:tt)*) => { |
296 | | $crate::macros::insert_toml( |
297 | | &mut $root, |
298 | | &[$(&concat!($("-", $crate::toml_internal!(@path $k),)+)[1..], )+], |
299 | | $crate::toml_internal!(@value $v)); |
300 | | $crate::toml_internal!(@table $root $($rest)*); |
301 | | }; |
302 | | |
303 | | // Parse a Datetime from string and continue in @table state. |
304 | | (@tabledatetime $root:ident $($($k:tt)-+).+ = ($($datetime:tt)*) $($rest:tt)*) => { |
305 | | $crate::macros::insert_toml( |
306 | | &mut $root, |
307 | | &[$(&concat!($("-", $crate::toml_internal!(@path $k),)+)[1..], )+], |
308 | | $crate::Value::Datetime(concat!($(stringify!($datetime)),+).parse().unwrap())); |
309 | | $crate::toml_internal!(@table $root $($rest)*); |
310 | | }; |
311 | | |
312 | | // Base case of inline array. |
313 | | (@array $root:ident) => {}; |
314 | | |
315 | | // Parse negative number `-value`. |
316 | | (@array $root:ident - $v:tt , $($rest:tt)*) => { |
317 | | $crate::toml_internal!(@array $root (-$v) , $($rest)*); |
318 | | }; |
319 | | |
320 | | // Parse positive number `+value`. |
321 | | (@array $root:ident + $v:tt , $($rest:tt)*) => { |
322 | | $crate::toml_internal!(@array $root ($v) , $($rest)*); |
323 | | }; |
324 | | |
325 | | // Parse offset datetime `1979-05-27T00:32:00.999999-07:00`. |
326 | | (@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => { |
327 | | $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec . $frac - $tzh : $tzm) $($rest)*); |
328 | | }; |
329 | | // Space instead of T. |
330 | | (@array $root:ident $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => { |
331 | | $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day T $hr : $min : $sec . $frac - $tzh : $tzm) $($rest)*); |
332 | | }; |
333 | | |
334 | | // Parse offset datetime `1979-05-27T00:32:00-07:00`. |
335 | | (@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => { |
336 | | $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec - $tzh : $tzm) $($rest)*); |
337 | | }; |
338 | | // Space instead of T. |
339 | | (@array $root:ident $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => { |
340 | | $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day T $hr : $min : $sec - $tzh : $tzm) $($rest)*); |
341 | | }; |
342 | | |
343 | | // Parse local datetime `1979-05-27T00:32:00.999999`. |
344 | | (@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => { |
345 | | $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec . $frac) $($rest)*); |
346 | | }; |
347 | | // Space instead of T. |
348 | | (@array $root:ident $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => { |
349 | | $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day T $hr : $min : $sec . $frac) $($rest)*); |
350 | | }; |
351 | | |
352 | | // Parse offset datetime `1979-05-27T07:32:00Z` and local datetime `1979-05-27T07:32:00`. |
353 | | (@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt , $($rest:tt)*) => { |
354 | | $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec) $($rest)*); |
355 | | }; |
356 | | // Space instead of T. |
357 | | (@array $root:ident $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt , $($rest:tt)*) => { |
358 | | $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day T $hr : $min : $sec) $($rest)*); |
359 | | }; |
360 | | |
361 | | // Parse local date `1979-05-27`. |
362 | | (@array $root:ident $yr:tt - $mo:tt - $day:tt , $($rest:tt)*) => { |
363 | | $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day) $($rest)*); |
364 | | }; |
365 | | |
366 | | // Parse local time `00:32:00.999999`. |
367 | | (@array $root:ident $hr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => { |
368 | | $crate::toml_internal!(@arraydatetime $root ($hr : $min : $sec . $frac) $($rest)*); |
369 | | }; |
370 | | |
371 | | // Parse local time `07:32:00`. |
372 | | (@array $root:ident $hr:tt : $min:tt : $sec:tt , $($rest:tt)*) => { |
373 | | $crate::toml_internal!(@arraydatetime $root ($hr : $min : $sec) $($rest)*); |
374 | | }; |
375 | | |
376 | | // Parse any other type, probably string or boolean or number. |
377 | | (@array $root:ident $v:tt , $($rest:tt)*) => { |
378 | | $root.push($crate::toml_internal!(@value $v)); |
379 | | $crate::toml_internal!(@array $root $($rest)*); |
380 | | }; |
381 | | |
382 | | // Parse a Datetime from string and continue in @array state. |
383 | | (@arraydatetime $root:ident ($($datetime:tt)*) $($rest:tt)*) => { |
384 | | $root.push($crate::Value::Datetime(concat!($(stringify!($datetime)),+).parse().unwrap())); |
385 | | $crate::toml_internal!(@array $root $($rest)*); |
386 | | }; |
387 | | |
388 | | // No trailing comma required if the tokens are empty. |
389 | | (@trailingcomma ($($args:tt)*)) => { |
390 | | $crate::toml_internal!($($args)*); |
391 | | }; |
392 | | |
393 | | // Tokens end with a trailing comma, do not append another one. |
394 | | (@trailingcomma ($($args:tt)*) ,) => { |
395 | | $crate::toml_internal!($($args)* ,); |
396 | | }; |
397 | | |
398 | | // Tokens end with something other than comma, append a trailing comma. |
399 | | (@trailingcomma ($($args:tt)*) $last:tt) => { |
400 | | $crate::toml_internal!($($args)* $last ,); |
401 | | }; |
402 | | |
403 | | // Not yet at the last token. |
404 | | (@trailingcomma ($($args:tt)*) $first:tt $($rest:tt)+) => { |
405 | | $crate::toml_internal!(@trailingcomma ($($args)* $first) $($rest)+); |
406 | | }; |
407 | | } |
408 | | |
409 | | // Called when parsing a `key = value` pair. |
410 | | // Inserts an entry into the table at the given path. |
411 | 0 | pub fn insert_toml(root: &mut Value, path: &[&str], value: Value) { |
412 | 0 | *traverse(root, path) = value; |
413 | 0 | } |
414 | | |
415 | | // Called when parsing an `[[array header]]`. |
416 | | // Pushes an empty table onto the array at the given path. |
417 | 0 | pub fn push_toml(root: &mut Value, path: &[&str]) { |
418 | 0 | let target = traverse(root, path); |
419 | 0 | if !target.is_array() { |
420 | 0 | *target = Value::Array(Array::new()); |
421 | 0 | } |
422 | 0 | target |
423 | 0 | .as_array_mut() |
424 | 0 | .unwrap() |
425 | 0 | .push(Value::Table(Table::new())); |
426 | 0 | } |
427 | | |
428 | 0 | fn traverse<'a>(root: &'a mut Value, path: &[&str]) -> &'a mut Value { |
429 | 0 | let mut cur = root; |
430 | 0 | for &key in path { |
431 | | // Lexical lifetimes :D |
432 | 0 | let cur1 = cur; |
433 | | |
434 | | // From the TOML spec: |
435 | | // |
436 | | // > Each double-bracketed sub-table will belong to the most recently |
437 | | // > defined table element above it. |
438 | 0 | let cur2 = if cur1.is_array() { |
439 | 0 | cur1.as_array_mut().unwrap().last_mut().unwrap() |
440 | | } else { |
441 | 0 | cur1 |
442 | | }; |
443 | | |
444 | | // We are about to index into this value, so it better be a table. |
445 | 0 | if !cur2.is_table() { |
446 | 0 | *cur2 = Value::Table(Table::new()); |
447 | 0 | } |
448 | | |
449 | 0 | if !cur2.as_table().unwrap().contains_key(key) { |
450 | 0 | // Insert an empty table for the next loop iteration to point to. |
451 | 0 | let empty = Value::Table(Table::new()); |
452 | 0 | cur2.as_table_mut().unwrap().insert(key.to_owned(), empty); |
453 | 0 | } |
454 | | |
455 | | // Step into the current table. |
456 | 0 | cur = cur2.as_table_mut().unwrap().get_mut(key).unwrap(); |
457 | | } |
458 | 0 | cur |
459 | 0 | } |