#[macro_export(local_inner_macros)]
macro_rules! json {
(@array [$($elems:expr,)*]) => {
json_vec![$($elems,)*]
};
(@array [$($elems:expr),*]) => {
json_vec![$($elems),*]
};
(@array [$($elems:expr,)*] null @ $meta:expr $(,$($rest:tt)*)?) => {
json!(@array [$($elems,)* json!(null @ $meta)] $(,$($rest)*)?)
};
(@array [$($elems:expr,)*] null $($rest:tt)*) => {
json!(@array [$($elems,)* json!(null)] $($rest)*)
};
(@array [$($elems:expr,)*] true @ $meta:expr $(,$($rest:tt)*)?) => {
json!(@array [$($elems,)* json!(true @ $meta)] $(,$($rest)*)?)
};
(@array [$($elems:expr,)*] true $($rest:tt)*) => {
json!(@array [$($elems,)* json!(true)] $($rest)*)
};
(@array [$($elems:expr,)*] false @ $meta:expr $(,$($rest:tt)*)?) => {
json!(@array [$($elems,)* json!(false @ $meta)] $(,$($rest)*)?)
};
(@array [$($elems:expr,)*] false $($rest:tt)*) => {
json!(@array [$($elems,)* json!(false)] $($rest)*)
};
(@array [$($elems:expr,)*] $lit:literal @ $meta:expr $(,$($rest:tt)*)?) => {
json!(@array [$($elems,)* json!($lit @ $meta)] $(,$($rest)*)?)
};
(@array [$($elems:expr,)*] $lit:literal $($rest:tt)*) => {
json!(@array [$($elems,)* json!($lit)] $($rest)*)
};
(@array [$($elems:expr,)*] [$($array:tt)*] @ $meta:expr $(,$($rest:tt)*)?) => {
json!(@array [$($elems,)* json!([$($array)*] @ $meta)] $(,$($rest)*)?)
};
(@array [$($elems:expr,)*] [$($array:tt)*] $($rest:tt)*) => {
json!(@array [$($elems,)* json!([$($array)*])] $($rest)*)
};
(@array [$($elems:expr,)*] {$($map:tt)*} @ $meta:expr $(,$($rest:tt)*)?) => {
json!(@array [$($elems,)* json!({$($map)*} @ $meta)] $(,$($rest)*)?)
};
(@array [$($elems:expr,)*] {$($map:tt)*} $($rest:tt)*) => {
json!(@array [$($elems,)* json!({$($map)*})] $($rest)*)
};
(@array [$($elems:expr,)*] $next:expr, $($rest:tt)*) => {
json!(@array [$($elems,)* json!($next),] $($rest)*)
};
(@array [$($elems:expr,)*] $last:expr) => {
json!(@array [$($elems,)* json!($last)])
};
(@array [$($elems:expr),*] , $($rest:tt)*) => {
json!(@array [$($elems,)*] $($rest)*)
};
(@array [$($elems:expr),*] $unexpected:tt $($rest:tt)*) => {
json_unexpected!($unexpected)
};
(@object [$($elems:expr,)*] () () ()) => {
$crate::Object::from_vec(json_vec![$($elems,)*])
};
(@object [$($elems:expr),*] () () ()) => {
$crate::Object::from_vec(json_vec![$($elems),*])
};
(@key (($key:literal @ $meta:expr))) => {
::locspan::Meta($key.into(), $meta)
};
(@key ($key:literal)) => {
::locspan::Meta($key.into(), ())
};
(@key ($key:expr)) => {
$key.into()
};
(@object [$($elems:expr,)*] ($($key:tt)+) (: null @ $meta:expr $(,$($rest:tt)*)?) $copy:tt) => {
json!(@object [$($elems,)* $crate::object::Entry::new(json!(@key ($($key)+)), json!(null @ $meta))] () ($(,$($rest)*)?) ($(,$($rest)*)?))
};
(@object [$($elems:expr,)*] ($($key:tt)+) (: null $($rest:tt)*) $copy:tt) => {
json!(@object [$($elems,)* $crate::object::Entry::new(json!(@key ($($key)+)), json!(null))] () ($($rest)*) ($($rest)*))
};
(@object [$($elems:expr,)*] ($($key:tt)+) (: true @ $meta:expr $(,$($rest:tt)*)?) $copy:tt) => {
json!(@object [$($elems,)* $crate::object::Entry::new(json!(@key ($($key)+)), json!(true @ $meta))] () ($(,$($rest)*)?) ($(,$($rest)*)?))
};
(@object [$($elems:expr,)*] ($($key:tt)+) (: true $($rest:tt)*) $copy:tt) => {
json!(@object [$($elems,)* $crate::object::Entry::new(json!(@key ($($key)+)), json!(true))] () ($($rest)*) ($($rest)*))
};
(@object [$($elems:expr,)*] ($($key:tt)+) (: false @ $meta:expr $(,$($rest:tt)*)?) $copy:tt) => {
json!(@object [$($elems,)* $crate::object::Entry::new(json!(@key ($($key)+)), json!(false @ $meta))] () ($(,$($rest)*)?) ($(,$($rest)*)?))
};
(@object [$($elems:expr,)*] ($($key:tt)+) (: false $($rest:tt)*) $copy:tt) => {
json!(@object [$($elems,)* $crate::object::Entry::new(json!(@key ($($key)+)), json!(false))] () ($($rest)*) ($($rest)*))
};
(@object [$($elems:expr,)*] ($($key:tt)+) (: $lit:literal @ $meta:expr $(,$($rest:tt)*)?) $copy:tt) => {
json!(@object [$($elems,)* $crate::object::Entry::new(json!(@key ($($key)+)), json!($lit @ $meta))] () ($(,$($rest)*)?) ($(,$($rest)*)?))
};
(@object [$($elems:expr,)*] ($($key:tt)+) (: $lit:literal $($rest:tt)*) $copy:tt) => {
json!(@object [$($elems,)* $crate::object::Entry::new(json!(@key ($($key)+)), json!($lit))] () ($($rest)*) ($($rest)*))
};
(@object [$($elems:expr,)*] ($($key:tt)+) (: [$($array:tt)*] @ $meta:expr $(,$($rest:tt)*)?) $copy:tt) => {
json!(@object [$($elems,)* $crate::object::Entry::new(json!(@key ($($key)+)), json!([$($array)*] @ $meta))] () ($(,$($rest)*)?) ($(,$($rest)*)?))
};
(@object [$($elems:expr,)*] ($($key:tt)+) (: [$($array:tt)*] $($rest:tt)*) $copy:tt) => {
json!(@object [$($elems,)* $crate::object::Entry::new(json!(@key ($($key)+)), json!([$($array)*]))] () ($($rest)*) ($($rest)*))
};
(@object [$($elems:expr,)*] ($($key:tt)+) (: {$($map:tt)*} @ $meta:expr $(,$($rest:tt)*)?) $copy:tt) => {
json!(@object [$($elems,)* $crate::object::Entry::new(json!(@key ($($key)+)), json!({$($map)*} @ $meta))] () ($(,$($rest)*)?) ($(,$($rest)*)?))
};
(@object [$($elems:expr,)*] ($($key:tt)+) (: {$($map:tt)*} $($rest:tt)*) $copy:tt) => {
json!(@object [$($elems,)* $crate::object::Entry::new(json!(@key ($($key)+)), json!({$($map)*}))] () ($($rest)*) ($($rest)*))
};
(@object [$($elems:expr,)*] ($($key:tt)+) (: $next:expr, $($rest:tt)*) $copy:tt) => {
json!(@object [$($elems,)* $crate::object::Entry::new(json!(@key ($($key)+)), json!($next)),] () ($($rest)*) ($($rest)*))
};
(@object [$($elems:expr,)*] ($($key:tt)+) (: $last:expr) $copy:tt) => {
json!(@object [$($elems,)* $crate::object::Entry::new(json!(@key ($($key)+)), json!($last))] () () ())
};
(@object [$($elems:expr),*] () (, $($rest:tt)*) $copy:tt) => {
json!(@object [$($elems,)*] () ($($rest)*) ($($rest)*))
};
(@object [$($elems:expr,)*] ($($key:tt)+) (:) $copy:tt) => {
json!()
};
(@object [$($elems:expr,)*] ($($key:tt)+) () $copy:tt) => {
json!()
};
(@object [$($elems:expr,)*] () (: $($rest:tt)*) ($colon:tt $($copy:tt)*)) => {
json_unexpected!($colon)
};
(@object [$($elems:expr,)*] ($($key:tt)*) (, $($rest:tt)*) ($comma:tt $($copy:tt)*)) => {
json_unexpected!($comma)
};
(@object [$($elems:expr,)*] () (($key:expr) : $($rest:tt)*) $copy:tt) => {
json!(@object [$($elems,)*] ($key) (: $($rest)*) (: $($rest)*))
};
(@object [$($elems:expr,)*] ($($key:tt)*) (: $($unexpected:tt)+) $copy:tt) => {
json_expect_expr_comma!($($unexpected)+)
};
(@object [$($elems:expr,)*] ($($key:tt)*) ($tt:tt $($rest:tt)*) $copy:tt) => {
json!(@object [$($elems,)*] ($($key)* $tt) ($($rest)*) ($($rest)*))
};
(null @ $meta:expr) => {
::locspan::Meta($crate::Value::Null, $meta)
};
(null) => {
json!(null @ ())
};
(true @ $meta:expr) => {
::locspan::Meta($crate::Value::Boolean(true), $meta)
};
(true) => {
json!(true @ ())
};
(false @ $meta:expr) => {
::locspan::Meta($crate::Value::Boolean(false), $meta)
};
(false) => {
json!(false @ ())
};
($lit:literal @ $meta:expr) => {
::locspan::Meta($lit.try_into().unwrap(), $meta)
};
($lit:literal) => {
json!($lit @ ())
};
([] @ $meta:expr) => {
::locspan::Meta($crate::Value::Array(json_vec![]), $meta)
};
([]) => {
json!([] @ ())
};
([ $($tt:tt)+ ] @ $meta:expr) => {
::locspan::Meta($crate::Value::Array(json!(@array [] $($tt)+)), $meta)
};
([ $($tt:tt)+ ]) => {
json!([ $($tt)+ ] @ ())
};
({} @ $meta:expr) => {
::locspan::Meta($crate::Value::Object($crate::Object::new()), $meta)
};
({}) => {
json!({} @ ())
};
({ $($tt:tt)+ } @ $meta:expr) => {
::locspan::Meta($crate::Value::Object(json!(@object [] () ($($tt)+) ($($tt)+))), $meta)
};
({ $($tt:tt)+ }) => {
json!({ $($tt)+ } @ ())
};
($other:expr) => {
$other.into()
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! json_vec {
($($content:tt)*) => {
vec![$($content)*]
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! json_unexpected {
() => {};
}
#[macro_export]
#[doc(hidden)]
macro_rules! json_expect_expr_comma {
($e:expr , $($tt:tt)*) => {};
}