macro_rules! value_subtype_impls {
($t:ty, $cf:ident, $rcf:ident, $mcf:ident) => {
impl std::convert::AsRef<crate::IValue> for $t {
fn as_ref(&self) -> &crate::IValue {
&self.0
}
}
impl std::convert::AsMut<crate::IValue> for $t {
fn as_mut(&mut self) -> &mut crate::IValue {
&mut self.0
}
}
impl std::borrow::Borrow<crate::IValue> for $t {
fn borrow(&self) -> &crate::IValue {
&self.0
}
}
impl std::borrow::BorrowMut<crate::IValue> for $t {
fn borrow_mut(&mut self) -> &mut crate::IValue {
&mut self.0
}
}
impl std::convert::From<$t> for crate::IValue {
fn from(other: $t) -> Self {
other.0
}
}
impl std::convert::TryFrom<crate::IValue> for $t {
type Error = crate::IValue;
fn try_from(other: crate::IValue) -> Result<Self, crate::IValue> {
other.$cf()
}
}
impl<'a> std::convert::TryFrom<&'a crate::IValue> for &'a $t {
type Error = ();
fn try_from(other: &'a crate::IValue) -> Result<Self, ()> {
other.$rcf().ok_or(())
}
}
impl<'a> std::convert::TryFrom<&'a mut crate::IValue> for &'a mut $t {
type Error = ();
fn try_from(other: &'a mut crate::IValue) -> Result<Self, ()> {
other.$mcf().ok_or(())
}
}
};
}
macro_rules! typed_conversions {
($(
$interm:ty: $(
$src:ty
$(where ($($gb:tt)*))*
),*;
)*) => {
$(
$(
impl $(<$($gb)*>)* From<$src> for IValue {
fn from(other: $src) -> Self {
<$interm>::from(other).into()
}
}
)*
)*
}
}
#[macro_export(local_inner_macros)]
macro_rules! ijson {
($($json:tt)+) => {
$crate::ijson_internal!($($json)+)
};
}
#[macro_export(local_inner_macros)]
#[doc(hidden)]
macro_rules! ijson_internal {
(@array $array:ident) => {};
(@array $array:ident ,) => {};
(@array $array:ident , null $($rest:tt)*) => {
$array.push(ijson_internal!(null));
ijson_internal!(@array $array $($rest)*)
};
(@array $array:ident , true $($rest:tt)*) => {
$array.push(ijson_internal!(true));
ijson_internal!(@array $array $($rest)*)
};
(@array $array:ident , false $($rest:tt)*) => {
$array.push(ijson_internal!(false));
ijson_internal!(@array $array $($rest)*)
};
(@array $array:ident , [$($arr:tt)*] $($rest:tt)*) => {
$array.push(ijson_internal!([$($arr)*]));
ijson_internal!(@array $array $($rest)*)
};
(@array $array:ident , {$($obj:tt)*} $($rest:tt)*) => {
$array.push(ijson_internal!({$($obj)*}));
ijson_internal!(@array $array $($rest)*)
};
(@array $array:ident , $next:expr , $($rest:tt)*) => {
$array.push(ijson_internal!($next));
ijson_internal!(@array $array , $($rest)*)
};
(@array $array:ident , $last:expr) => {
$array.push(ijson_internal!($last));
};
(@array $array:ident , $unexpected:tt $($rest:tt)*) => {
ijson_unexpected!($unexpected)
};
(@array $array:ident $unexpected:tt $($rest:tt)*) => {
ijson_unexpected!($unexpected)
};
(@object $object:ident () () ()) => {};
(@object $object:ident [$($key:tt)+] ($value:expr) , $($rest:tt)*) => {
let _ = $object.insert(($($key)+), $value);
ijson_internal!(@object $object () ($($rest)*) ($($rest)*));
};
(@object $object:ident [$($key:tt)+] ($value:expr) $unexpected:tt $($rest:tt)*) => {
ijson_unexpected!($unexpected);
};
(@object $object:ident [$($key:tt)+] ($value:expr)) => {
let _ = $object.insert(($($key)+), $value);
};
(@object $object:ident ($($key:tt)+) (: null $($rest:tt)*) $copy:tt) => {
ijson_internal!(@object $object [$($key)+] (ijson_internal!(null)) $($rest)*);
};
(@object $object:ident ($($key:tt)+) (: true $($rest:tt)*) $copy:tt) => {
ijson_internal!(@object $object [$($key)+] (ijson_internal!(true)) $($rest)*);
};
(@object $object:ident ($($key:tt)+) (: false $($rest:tt)*) $copy:tt) => {
ijson_internal!(@object $object [$($key)+] (ijson_internal!(false)) $($rest)*);
};
(@object $object:ident ($($key:tt)+) (: [$($array:tt)*] $($rest:tt)*) $copy:tt) => {
ijson_internal!(@object $object [$($key)+] (ijson_internal!([$($array)*])) $($rest)*);
};
(@object $object:ident ($($key:tt)+) (: {$($map:tt)*} $($rest:tt)*) $copy:tt) => {
ijson_internal!(@object $object [$($key)+] (ijson_internal!({$($map)*})) $($rest)*);
};
(@object $object:ident ($($key:tt)+) (: $value:expr , $($rest:tt)*) $copy:tt) => {
ijson_internal!(@object $object [$($key)+] (ijson_internal!($value)) , $($rest)*);
};
(@object $object:ident ($($key:tt)+) (: $value:expr) $copy:tt) => {
ijson_internal!(@object $object [$($key)+] (ijson_internal!($value)));
};
(@object $object:ident ($($key:tt)+) (:) $copy:tt) => {
ijson_internal!();
};
(@object $object:ident ($($key:tt)+) () $copy:tt) => {
ijson_internal!();
};
(@object $object:ident () (: $($rest:tt)*) ($colon:tt $($copy:tt)*)) => {
ijson_unexpected!($colon);
};
(@object $object:ident ($($key:tt)*) (, $($rest:tt)*) ($comma:tt $($copy:tt)*)) => {
ijson_unexpected!($comma);
};
(@object $object:ident () (($key:expr) : $($rest:tt)*) $copy:tt) => {
ijson_internal!(@object $object ($key) (: $($rest)*) (: $($rest)*));
};
(@object $object:ident ($($key:tt)*) (: $($unexpected:tt)+) $copy:tt) => {
ijson_expect_expr_comma!($($unexpected)+);
};
(@object $object:ident ($($key:tt)*) ($tt:tt $($rest:tt)*) $copy:tt) => {
ijson_internal!(@object $object ($($key)* $tt) ($($rest)*) ($($rest)*));
};
(null) => {
$crate::IValue::NULL
};
(true) => {
$crate::IValue::TRUE
};
(false) => {
$crate::IValue::FALSE
};
([]) => {
$crate::IValue::from($crate::IArray::new())
};
([ $($tt:tt)+ ]) => {
$crate::IValue::from({
let mut array = $crate::IArray::new();
ijson_internal!(@array array , $($tt)+);
array
})
};
({}) => {
$crate::IValue::from($crate::IObject::new())
};
({ $($tt:tt)+ }) => {
$crate::IValue::from({
let mut object = $crate::IObject::new();
ijson_internal!(@object object () ($($tt)+) ($($tt)+));
object
})
};
($other:expr) => {
$crate::to_value(&$other).unwrap()
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! ijson_unexpected {
() => {};
}
#[macro_export]
#[doc(hidden)]
macro_rules! ijson_expect_expr_comma {
($e:expr , $($tt:tt)*) => {};
}