1pub use serde::de::{Deserialize, IntoDeserializer};
2
3use crate::value::{Array, Table, Value};
4
5#[macro_export]
32macro_rules! toml {
33 ($($toml:tt)+) => {{
34 let table = $crate::value::Table::new();
35 let mut root = $crate::Value::Table(table);
36 $crate::toml_internal!(@toplevel root [] $($toml)+);
37 root
38 }};
39}
40
41#[macro_export]
74#[doc(hidden)]
75macro_rules! toml_internal {
76 (@toplevel $root:ident [$($path:tt)*]) => {};
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)-+).+ = + $v:tt $($rest:tt)*) => {
86 $crate::toml_internal!(@toplevel $root [$($path)*] $($($k)-+).+ = ($v) $($rest)*);
87 };
88
89 (@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)*) => {
91 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
92 };
93 (@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)*) => {
95 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
96 };
97
98 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt $($rest:tt)*) => {
100 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec - $tzh : $tzm) $($rest)*);
101 };
102 (@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)*) => {
104 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec - $tzh : $tzm) $($rest)*);
105 };
106
107 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt $($rest:tt)*) => {
109 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec . $frac) $($rest)*);
110 };
111 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt $($rest:tt)*) => {
113 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec . $frac) $($rest)*);
114 };
115
116 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt $($rest:tt)*) => {
118 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec) $($rest)*);
119 };
120 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt $($rest:tt)*) => {
122 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec) $($rest)*);
123 };
124
125 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $($rest:tt)*) => {
127 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day) $($rest)*);
128 };
129
130 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $hr:tt : $min:tt : $sec:tt . $frac:tt $($rest:tt)*) => {
132 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($hr : $min : $sec . $frac) $($rest)*);
133 };
134
135 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $hr:tt : $min:tt : $sec:tt $($rest:tt)*) => {
137 $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($hr : $min : $sec) $($rest)*);
138 };
139
140 (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $v:tt $($rest:tt)*) => {{
143 $crate::macros::insert_toml(
144 &mut $root,
145 &[$($path)* $(&concat!($("-", $crate::toml_internal!(@path $k),)+)[1..], )+],
146 $crate::toml_internal!(@value $v));
147 $crate::toml_internal!(@toplevel $root [$($path)*] $($rest)*);
148 }};
149
150 (@toplevel $root:ident $oldpath:tt [[$($($path:tt)-+).+]] $($rest:tt)*) => {
152 $crate::macros::push_toml(
153 &mut $root,
154 &[$(&concat!($("-", $crate::toml_internal!(@path $path),)+)[1..],)+]);
155 $crate::toml_internal!(@toplevel $root [$(&concat!($("-", $crate::toml_internal!(@path $path),)+)[1..],)+] $($rest)*);
156 };
157
158 (@toplevel $root:ident $oldpath:tt [$($($path:tt)-+).+] $($rest:tt)*) => {
160 $crate::macros::insert_toml(
161 &mut $root,
162 &[$(&concat!($("-", $crate::toml_internal!(@path $path),)+)[1..],)+],
163 $crate::Value::Table($crate::value::Table::new()));
164 $crate::toml_internal!(@toplevel $root [$(&concat!($("-", $crate::toml_internal!(@path $path),)+)[1..],)+] $($rest)*);
165 };
166
167 (@topleveldatetime $root:ident [$($path:tt)*] $($($k:tt)-+).+ = ($($datetime:tt)+) $($rest:tt)*) => {
169 $crate::macros::insert_toml(
170 &mut $root,
171 &[$($path)* $(&concat!($("-", $crate::toml_internal!(@path $k),)+)[1..], )+],
172 $crate::Value::Datetime(concat!($(stringify!($datetime)),+).parse().unwrap()));
173 $crate::toml_internal!(@toplevel $root [$($path)*] $($rest)*);
174 };
175
176 (@path $ident:ident) => {
178 stringify!($ident)
179 };
180
181 (@path $quoted:tt) => {
184 $quoted
185 };
186
187 (@value { $($inline:tt)* }) => {{
189 let mut table = $crate::Value::Table($crate::value::Table::new());
190 $crate::toml_internal!(@trailingcomma (@table table) $($inline)*);
191 table
192 }};
193
194 (@value [ $($inline:tt)* ]) => {{
196 let mut array = $crate::value::Array::new();
197 $crate::toml_internal!(@trailingcomma (@array array) $($inline)*);
198 $crate::Value::Array(array)
199 }};
200
201 (@value (-nan)) => {
202 $crate::Value::Float(-::std::f64::NAN)
203 };
204
205 (@value (nan)) => {
206 $crate::Value::Float(::std::f64::NAN)
207 };
208
209 (@value nan) => {
210 $crate::Value::Float(::std::f64::NAN)
211 };
212
213 (@value (-inf)) => {
214 $crate::Value::Float(::std::f64::NEG_INFINITY)
215 };
216
217 (@value (inf)) => {
218 $crate::Value::Float(::std::f64::INFINITY)
219 };
220
221 (@value inf) => {
222 $crate::Value::Float(::std::f64::INFINITY)
223 };
224
225 (@value $v:tt) => {{
227 let de = $crate::macros::IntoDeserializer::<$crate::de::Error>::into_deserializer($v);
229 <$crate::Value as $crate::macros::Deserialize>::deserialize(de).unwrap()
230 }};
231
232 (@table $root:ident) => {};
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)-+).+ = + $v:tt , $($rest:tt)*) => {
242 $crate::toml_internal!(@table $root $($($k)-+).+ = ($v) , $($rest)*);
243 };
244
245 (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
247 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
248 };
249 (@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)*) => {
251 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
252 };
253
254 (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
256 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec - $tzh : $tzm) $($rest)*);
257 };
258 (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
260 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec - $tzh : $tzm) $($rest)*);
261 };
262
263 (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
265 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec . $frac) $($rest)*);
266 };
267 (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
269 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec . $frac) $($rest)*);
270 };
271
272 (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
274 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec) $($rest)*);
275 };
276 (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
278 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec) $($rest)*);
279 };
280
281 (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt , $($rest:tt)*) => {
283 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day) $($rest)*);
284 };
285
286 (@table $root:ident $($($k:tt)-+).+ = $hr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
288 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($hr : $min : $sec . $frac) $($rest)*);
289 };
290
291 (@table $root:ident $($($k:tt)-+).+ = $hr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
293 $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($hr : $min : $sec) $($rest)*);
294 };
295
296 (@table $root:ident $($($k:tt)-+).+ = $v:tt , $($rest:tt)*) => {
298 $crate::macros::insert_toml(
299 &mut $root,
300 &[$(&concat!($("-", $crate::toml_internal!(@path $k),)+)[1..], )+],
301 $crate::toml_internal!(@value $v));
302 $crate::toml_internal!(@table $root $($rest)*);
303 };
304
305 (@tabledatetime $root:ident $($($k:tt)-+).+ = ($($datetime:tt)*) $($rest:tt)*) => {
307 $crate::macros::insert_toml(
308 &mut $root,
309 &[$(&concat!($("-", $crate::toml_internal!(@path $k),)+)[1..], )+],
310 $crate::Value::Datetime(concat!($(stringify!($datetime)),+).parse().unwrap()));
311 $crate::toml_internal!(@table $root $($rest)*);
312 };
313
314 (@array $root:ident) => {};
316
317 (@array $root:ident - $v:tt , $($rest:tt)*) => {
319 $crate::toml_internal!(@array $root (-$v) , $($rest)*);
320 };
321
322 (@array $root:ident + $v:tt , $($rest:tt)*) => {
324 $crate::toml_internal!(@array $root ($v) , $($rest)*);
325 };
326
327 (@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
329 $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
330 };
331 (@array $root:ident $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
333 $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day T $hr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
334 };
335
336 (@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
338 $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec - $tzh : $tzm) $($rest)*);
339 };
340 (@array $root:ident $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
342 $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day T $hr : $min : $sec - $tzh : $tzm) $($rest)*);
343 };
344
345 (@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
347 $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec . $frac) $($rest)*);
348 };
349 (@array $root:ident $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
351 $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day T $hr : $min : $sec . $frac) $($rest)*);
352 };
353
354 (@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
356 $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec) $($rest)*);
357 };
358 (@array $root:ident $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
360 $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day T $hr : $min : $sec) $($rest)*);
361 };
362
363 (@array $root:ident $yr:tt - $mo:tt - $day:tt , $($rest:tt)*) => {
365 $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day) $($rest)*);
366 };
367
368 (@array $root:ident $hr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
370 $crate::toml_internal!(@arraydatetime $root ($hr : $min : $sec . $frac) $($rest)*);
371 };
372
373 (@array $root:ident $hr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
375 $crate::toml_internal!(@arraydatetime $root ($hr : $min : $sec) $($rest)*);
376 };
377
378 (@array $root:ident $v:tt , $($rest:tt)*) => {
380 $root.push($crate::toml_internal!(@value $v));
381 $crate::toml_internal!(@array $root $($rest)*);
382 };
383
384 (@arraydatetime $root:ident ($($datetime:tt)*) $($rest:tt)*) => {
386 $root.push($crate::Value::Datetime(concat!($(stringify!($datetime)),+).parse().unwrap()));
387 $crate::toml_internal!(@array $root $($rest)*);
388 };
389
390 (@trailingcomma ($($args:tt)*)) => {
392 $crate::toml_internal!($($args)*);
393 };
394
395 (@trailingcomma ($($args:tt)*) ,) => {
397 $crate::toml_internal!($($args)* ,);
398 };
399
400 (@trailingcomma ($($args:tt)*) $last:tt) => {
402 $crate::toml_internal!($($args)* $last ,);
403 };
404
405 (@trailingcomma ($($args:tt)*) $first:tt $($rest:tt)+) => {
407 $crate::toml_internal!(@trailingcomma ($($args)* $first) $($rest)+);
408 };
409}
410
411pub fn insert_toml(root: &mut Value, path: &[&str], value: Value) {
414 *traverse(root, path) = value;
415}
416
417pub fn push_toml(root: &mut Value, path: &[&str]) {
420 let target = traverse(root, path);
421 if !target.is_array() {
422 *target = Value::Array(Array::new());
423 }
424 target
425 .as_array_mut()
426 .unwrap()
427 .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 let cur1 = cur;
435 let cur2;
436
437 if cur1.is_array() {
442 cur2 = cur1.as_array_mut().unwrap().last_mut().unwrap();
443 } else {
444 cur2 = cur1;
445 };
446
447 if !cur2.is_table() {
449 *cur2 = Value::Table(Table::new());
450 }
451
452 if !cur2.as_table().unwrap().contains_key(key) {
453 let empty = Value::Table(Table::new());
455 cur2.as_table_mut().unwrap().insert(key.to_owned(), empty);
456 }
457
458 cur = cur2.as_table_mut().unwrap().get_mut(key).unwrap();
460 }
461 cur
462}