#[macro_export]
macro_rules! tree {
($($tree:tt)+) => {
$crate::__tree!($($tree)+)
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __tree {
(@list [$($done:expr,)*]) => {
$crate::tree::__vec![$($done,)*]
};
(@list [$($done:expr),*]) => {
$crate::tree::__vec![$($done),*]
};
(@list [$($done:expr,)*] null $($rest:tt)*) => {
$crate::__tree!(@list [$($done,)* $crate::__tree!(null)] $($rest)*)
};
(@list [$($done:expr,)*] true $($rest:tt)*) => {
$crate::__tree!(@list [$($done,)* $crate::__tree!(true)] $($rest)*)
};
(@list [$($done:expr,)*] false $($rest:tt)*) => {
$crate::__tree!(@list [$($done,)* $crate::__tree!(false)] $($rest)*)
};
(@list [$($done:expr,)*] [$($list:tt)*] $($rest:tt)*) => {
$crate::__tree!(@list [$($done,)* $crate::__tree!([$($list)*])] $($rest)*)
};
(@list [$($done:expr,)*] {$($object:tt)*} $($rest:tt)*) => {
$crate::__tree!(@list [$($done,)* $crate::__tree!({$($object)*})] $($rest)*)
};
(@list [$($done:expr,)*] $next:expr, $($rest:tt)*) => {
$crate::__tree!(@list [$($done,)* $crate::__tree!($next),] $($rest)*)
};
(@list [$($done:expr,)*] $last:expr) => {
$crate::__tree!(@list [$($done,)* $crate::__tree!($last)])
};
(@list [$($done:expr),*] , $($rest:tt)*) => {
$crate::__tree!(@list [$($done,)*] $($rest)*)
};
(@object $object:ident () () ()) => {};
(@object $object:ident [$($name:tt)+] ($value:expr) , $($rest:tt)*) => {
let _ = $object.insert(($($name)+).into(), $value);
$crate::__tree!(@object $object () ($($rest)*) ($($rest)*));
};
(@object $object:ident [$($name:tt)+] ($value:expr)) => {
let _ = $object.insert(($($name)+).into(), $value);
};
(@object $object:ident ($($name:tt)+) (: null $($rest:tt)*) $copy:tt) => {
$crate::__tree!(@object $object [$($name)+] ($crate::__tree!(null)) $($rest)*);
};
(@object $object:ident ($($name:tt)+) (: true $($rest:tt)*) $copy:tt) => {
$crate::__tree!(@object $object [$($name)+] ($crate::__tree!(true)) $($rest)*);
};
(@object $object:ident ($($name:tt)+) (: false $($rest:tt)*) $copy:tt) => {
$crate::__tree!(@object $object [$($name)+] ($crate::__tree!(false)) $($rest)*);
};
(@object $object:ident ($($name:tt)+) (: [$($list:tt)*] $($rest:tt)*) $copy:tt) => {
$crate::__tree!(@object $object [$($name)+] ($crate::__tree!([$($list)*])) $($rest)*);
};
(@object $object:ident ($($name:tt)+) (: {$($inner:tt)*} $($rest:tt)*) $copy:tt) => {
$crate::__tree!(@object $object [$($name)+] ($crate::__tree!({$($inner)*})) $($rest)*);
};
(@object $object:ident ($($name:tt)+) (: $value:expr , $($rest:tt)*) $copy:tt) => {
$crate::__tree!(@object $object [$($name)+] ($crate::__tree!($value)) , $($rest)*);
};
(@object $object:ident ($($name:tt)+) (: $value:expr) $copy:tt) => {
$crate::__tree!(@object $object [$($name)+] ($crate::__tree!($value)));
};
(@object $object:ident () (($name:expr) : $($rest:tt)*) $copy:tt) => {
$crate::__tree!(@object $object ($name) (: $($rest)*) (: $($rest)*));
};
(@object $object:ident ($($name:tt)*) ($token:tt $($rest:tt)*) $copy:tt) => {
$crate::__tree!(@object $object ($($name)* $token) ($($rest)*) ($($rest)*));
};
(null) => {
$crate::tree::Value::Null
};
(true) => {
$crate::tree::Value::Bool(true)
};
(false) => {
$crate::tree::Value::Bool(false)
};
([]) => {
$crate::tree::Value::Array($crate::tree::__vec![])
};
([ $($list:tt)+ ]) => {
$crate::tree::Value::Array($crate::__tree!(@list [] $($list)+))
};
({}) => {
$crate::tree::Value::Object($crate::tree::Map::new())
};
({ $($members:tt)+ }) => {
$crate::tree::Value::Object({
let mut object = $crate::tree::Map::new();
$crate::__tree!(@object object () ($($members)+) ($($members)+));
object
})
};
($other:expr) => {
$crate::tree::Value::from($other)
};
}