#[macro_export(json_macros)]
macro_rules! obj{
{} => (
Obj::new()
);
(@key $key:literal) => (
$key.into()
);
(@key $key:ident) => (
stringify!($key)
);
(@key $key:expr) => (
$key.into()
);
(@set $json:ident ($($key:tt)+) ($($val:tt)+)) => (
$json.set(obj!(@key $($key)*), val!($($val)*));
);
(@set_and_continue $json:ident ($($key:tt)+) ($($val:tt)+) ($($rest:tt)+)) => (
obj!(@set $json ($($key)*) ($($val)*));
obj!(@flat_expr_or_continue $json ($($rest)*));
);
(@set_and_continue $json:ident ($($key:tt)+) ($($val:tt)+)) => (
obj!(@set $json ($($key)*) ($($val)*));
);
(@next_value $json:ident ($($key:tt)+) ($($rest:tt)+)) => (
val!(@next ($($rest)*) (obj!) (@set_and_continue $json ($($key)*)));
);
(@next_key $json:ident ($key:ident, $($rest:tt)+)) => (
obj!(@next_value $json ($key) ($key,$($rest)*));
);
(@next_key $json:ident ($key:ident)) => (
obj!(@next_value $json ($key) ($key));
);
(@next_key $json:ident ($key:literal: $($rest:tt)+)) => (
obj!(@next_value $json ($key) ($($rest)*));
);
(@next_key $json:ident ($key:ident: $($rest:tt)+)) => (
obj!(@next_value $json ($key) ($($rest)*));
);
(@next_key $json:ident ([$key:expr] : $($rest:tt)+)) => (
obj!(@next_value $json ($key) ($($rest)*));
);
(@flat_expr_or_continue $json:ident (...{$($val:tt)*}, $($rest:tt)*)) => (
$json.extend(obj!{$($val)*}.clone().into_iter());
obj!(@flat_expr_or_continue $json ($($rest)*));
);
(@flat_expr_or_continue $json:ident (...{$($val:tt)*})) => (
$json.extend(obj!{$($val)*}.clone().into_iter());
);
(@flat_expr_or_continue $json:ident (...$val:expr , $($rest:tt)*))=> (
$json.extend($val.clone().into_iter());
obj!(@flat_expr_or_continue $json ($($rest)*));
);
(@flat_expr_or_continue $json:ident (...$val:expr)) => (
$json.extend($val.clone().into_iter());
);
(@flat_expr_or_continue $json:ident ($($rest:tt)*)) => (
obj!(@next_key $json ($($rest)*));
);
{$($tt:tt)*} => (
{
let mut j = Obj::new();
obj!(@flat_expr_or_continue j ($($tt)*));
j
}
);
}