1pub use serde::de::{Deserialize, IntoDeserializer};
2
3use crate::alloc_prelude::*;
4use crate::value::{Array, Table, Value};
5
6#[macro_export]
24macro_rules! toml {
25 ($($toml:tt)+) => {{
26 let table = $crate::value::Table::new();
27 let mut root = $crate::Value::Table(table);
28 $crate::toml_internal!(@toplevel root [] $($toml)+);
29 match root {
30 $crate::Value::Table(table) => table,
31 _ => unreachable!(),
32 }
33 }};
34}
35
36#[macro_export]
69#[doc(hidden)]
70macro_rules! toml_internal {
71 (@toplevel $root:ident [$($path:tt)*]) => {};
73
74 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = - $v:tt $($rest:tt)*) => {
76 $crate::toml_internal!(@toplevel $root [$($path)*] $($($k)-+).+ = (-$v) $($rest)*);
77 };
78
79 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = + $v:tt $($rest:tt)*) => {
81 $crate::toml_internal!(@toplevel $root [$($path)*] $($($k)-+).+ = ($v) $($rest)*);
82 };
83
84 (@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)*) => {
86 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
87 };
88 (@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)*) => {
90 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
91 };
92
93 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt $($rest:tt)*) => {
95 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec - $tzh : $tzm) $($rest)*);
96 };
97 (@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)*) => {
99 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec - $tzh : $tzm) $($rest)*);
100 };
101
102 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt $($rest:tt)*) => {
104 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec . $frac) $($rest)*);
105 };
106 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt $($rest:tt)*) => {
108 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec . $frac) $($rest)*);
109 };
110
111 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt $($rest:tt)*) => {
113 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec) $($rest)*);
114 };
115 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt $($rest:tt)*) => {
117 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec) $($rest)*);
118 };
119
120 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $($rest:tt)*) => {
122 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day) $($rest)*);
123 };
124
125 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $hr:tt : $min:tt : $sec:tt . $frac:tt $($rest:tt)*) => {
127 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($hr : $min : $sec . $frac) $($rest)*);
128 };
129
130 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $hr:tt : $min:tt : $sec:tt $($rest:tt)*) => {
132 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($hr : $min : $sec) $($rest)*);
133 };
134
135 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $v:tt $($rest:tt)*) => {{
138 $crate::macros::insert_toml(
139 &mut $root,
140 &[$($path)* $(&concat!($("-", $crate::toml_internal!(@path $k),)+)[1..], )+],
141 $crate::toml_internal!(@value $v));
142 $crate::toml_internal!(@toplevel $root [$($path)*] $($rest)*);
143 }};
144
145 (@toplevel $root:ident $oldpath:tt [[$($($path:tt)-+).+]] $($rest:tt)*) => {
147 $crate::macros::push_toml(
148 &mut $root,
149 &[$(&concat!($("-", $crate::toml_internal!(@path $path),)+)[1..],)+]);
150 $crate::toml_internal!(@toplevel $root [$(&concat!($("-", $crate::toml_internal!(@path $path),)+)[1..],)+] $($rest)*);
151 };
152
153 (@toplevel $root:ident $oldpath:tt [$($($path:tt)-+).+] $($rest:tt)*) => {
155 $crate::macros::insert_toml(
156 &mut $root,
157 &[$(&concat!($("-", $crate::toml_internal!(@path $path),)+)[1..],)+],
158 $crate::Value::Table($crate::value::Table::new()));
159 $crate::toml_internal!(@toplevel $root [$(&concat!($("-", $crate::toml_internal!(@path $path),)+)[1..],)+] $($rest)*);
160 };
161
162 (@topleveldatetime $root:ident [$($path:tt)*] $($($k:tt)-+).+ = ($($datetime:tt)+) $($rest:tt)*) => {
164 $crate::macros::insert_toml(
165 &mut $root,
166 &[$($path)* $(&concat!($("-", $crate::toml_internal!(@path $k),)+)[1..], )+],
167 $crate::Value::Datetime(concat!($(stringify!($datetime)),+).parse().unwrap()));
168 $crate::toml_internal!(@toplevel $root [$($path)*] $($rest)*);
169 };
170
171 (@path $ident:ident) => {
173 stringify!($ident)
174 };
175
176 (@path $quoted:tt) => {
179 $quoted
180 };
181
182 (@value { $($inline:tt)* }) => {{
184 let mut table = $crate::Value::Table($crate::value::Table::new());
185 $crate::toml_internal!(@trailingcomma (@table table) $($inline)*);
186 table
187 }};
188
189 (@value [ $($inline:tt)* ]) => {{
191 let mut array = $crate::value::Array::new();
192 $crate::toml_internal!(@trailingcomma (@array array) $($inline)*);
193 $crate::Value::Array(array)
194 }};
195
196 (@value (-nan)) => {
197 $crate::Value::Float(::core::f64::NAN.copysign(-1.0))
198 };
199
200 (@value (nan)) => {
201 $crate::Value::Float(::core::f64::NAN.copysign(1.0))
202 };
203
204 (@value nan) => {
205 $crate::Value::Float(::core::f64::NAN.copysign(1.0))
206 };
207
208 (@value (-inf)) => {
209 $crate::Value::Float(::core::f64::NEG_INFINITY)
210 };
211
212 (@value (inf)) => {
213 $crate::Value::Float(::core::f64::INFINITY)
214 };
215
216 (@value inf) => {
217 $crate::Value::Float(::core::f64::INFINITY)
218 };
219
220 (@value $v:tt) => {{
222 let de = $crate::macros::IntoDeserializer::<$crate::de::Error>::into_deserializer($v);
224 <$crate::Value as $crate::macros::Deserialize>::deserialize(de).unwrap()
225 }};
226
227 (@table $root:ident) => {};
229
230 (@table $root:ident $($($k:tt)-+).+ = - $v:tt , $($rest:tt)*) => {
232 $crate::toml_internal!(@table $root $($($k)-+).+ = (-$v) , $($rest)*);
233 };
234
235 (@table $root:ident $($($k:tt)-+).+ = + $v:tt , $($rest:tt)*) => {
237 $crate::toml_internal!(@table $root $($($k)-+).+ = ($v) , $($rest)*);
238 };
239
240 (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
242 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
243 };
244 (@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)*) => {
246 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
247 };
248
249 (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
251 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec - $tzh : $tzm) $($rest)*);
252 };
253 (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
255 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec - $tzh : $tzm) $($rest)*);
256 };
257
258 (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
260 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec . $frac) $($rest)*);
261 };
262 (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
264 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec . $frac) $($rest)*);
265 };
266
267 (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
269 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec) $($rest)*);
270 };
271 (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
273 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec) $($rest)*);
274 };
275
276 (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt , $($rest:tt)*) => {
278 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day) $($rest)*);
279 };
280
281 (@table $root:ident $($($k:tt)-+).+ = $hr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
283 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($hr : $min : $sec . $frac) $($rest)*);
284 };
285
286 (@table $root:ident $($($k:tt)-+).+ = $hr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
288 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($hr : $min : $sec) $($rest)*);
289 };
290
291 (@table $root:ident $($($k:tt)-+).+ = $v:tt , $($rest:tt)*) => {
293 $crate::macros::insert_toml(
294 &mut $root,
295 &[$(&concat!($("-", $crate::toml_internal!(@path $k),)+)[1..], )+],
296 $crate::toml_internal!(@value $v));
297 $crate::toml_internal!(@table $root $($rest)*);
298 };
299
300 (@tabledatetime $root:ident $($($k:tt)-+).+ = ($($datetime:tt)*) $($rest:tt)*) => {
302 $crate::macros::insert_toml(
303 &mut $root,
304 &[$(&concat!($("-", $crate::toml_internal!(@path $k),)+)[1..], )+],
305 $crate::Value::Datetime(concat!($(stringify!($datetime)),+).parse().unwrap()));
306 $crate::toml_internal!(@table $root $($rest)*);
307 };
308
309 (@array $root:ident) => {};
311
312 (@array $root:ident - $v:tt , $($rest:tt)*) => {
314 $crate::toml_internal!(@array $root (-$v) , $($rest)*);
315 };
316
317 (@array $root:ident + $v:tt , $($rest:tt)*) => {
319 $crate::toml_internal!(@array $root ($v) , $($rest)*);
320 };
321
322 (@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
324 $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
325 };
326 (@array $root:ident $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
328 $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day T $hr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
329 };
330
331 (@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
333 $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec - $tzh : $tzm) $($rest)*);
334 };
335 (@array $root:ident $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
337 $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day T $hr : $min : $sec - $tzh : $tzm) $($rest)*);
338 };
339
340 (@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
342 $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec . $frac) $($rest)*);
343 };
344 (@array $root:ident $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
346 $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day T $hr : $min : $sec . $frac) $($rest)*);
347 };
348
349 (@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
351 $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec) $($rest)*);
352 };
353 (@array $root:ident $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
355 $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day T $hr : $min : $sec) $($rest)*);
356 };
357
358 (@array $root:ident $yr:tt - $mo:tt - $day:tt , $($rest:tt)*) => {
360 $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day) $($rest)*);
361 };
362
363 (@array $root:ident $hr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
365 $crate::toml_internal!(@arraydatetime $root ($hr : $min : $sec . $frac) $($rest)*);
366 };
367
368 (@array $root:ident $hr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
370 $crate::toml_internal!(@arraydatetime $root ($hr : $min : $sec) $($rest)*);
371 };
372
373 (@array $root:ident $v:tt , $($rest:tt)*) => {
375 $root.push($crate::toml_internal!(@value $v));
376 $crate::toml_internal!(@array $root $($rest)*);
377 };
378
379 (@arraydatetime $root:ident ($($datetime:tt)*) $($rest:tt)*) => {
381 $root.push($crate::Value::Datetime(concat!($(stringify!($datetime)),+).parse().unwrap()));
382 $crate::toml_internal!(@array $root $($rest)*);
383 };
384
385 (@trailingcomma ($($args:tt)*)) => {
387 $crate::toml_internal!($($args)*);
388 };
389
390 (@trailingcomma ($($args:tt)*) ,) => {
392 $crate::toml_internal!($($args)* ,);
393 };
394
395 (@trailingcomma ($($args:tt)*) $last:tt) => {
397 $crate::toml_internal!($($args)* $last ,);
398 };
399
400 (@trailingcomma ($($args:tt)*) $first:tt $($rest:tt)+) => {
402 $crate::toml_internal!(@trailingcomma ($($args)* $first) $($rest)+);
403 };
404}
405
406pub fn insert_toml(root: &mut Value, path: &[&str], value: Value) {
409 *traverse(root, path) = value;
410}
411
412pub fn push_toml(root: &mut Value, path: &[&str]) {
415 let target = traverse(root, path);
416 if !target.is_array() {
417 *target = Value::Array(Array::new());
418 }
419 target
420 .as_array_mut()
421 .unwrap()
422 .push(Value::Table(Table::new()));
423}
424
425fn traverse<'a>(root: &'a mut Value, path: &[&str]) -> &'a mut Value {
426 let mut cur = root;
427 for &key in path {
428 let cur1 = cur;
430
431 let cur2 = if cur1.is_array() {
436 cur1.as_array_mut().unwrap().last_mut().unwrap()
437 } else {
438 cur1
439 };
440
441 if !cur2.is_table() {
443 *cur2 = Value::Table(Table::new());
444 }
445
446 if !cur2.as_table().unwrap().contains_key(key) {
447 let empty = Value::Table(Table::new());
449 cur2.as_table_mut().unwrap().insert(key.to_owned(), empty);
450 }
451
452 cur = cur2.as_table_mut().unwrap().get_mut(key).unwrap();
454 }
455 cur
456}