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