Coverage Report

Created: 2025-06-02 07:01

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