#[macro_export]
macro_rules! object {
($($t:tt)*) => { $crate::__declare!(__both_impls $($t)*); };
}
#[macro_export]
macro_rules! json_object {
($($t:tt)*) => { $crate::__declare!(__json_impls $($t)*); };
}
#[macro_export]
macro_rules! beve_object {
($($t:tt)*) => { $crate::__declare!(__beve_impls $($t)*); };
}
#[doc(hidden)]
#[macro_export]
macro_rules! __declare {
($m:ident [ 'de $($gen:tt)* ] $ty:ty as $case:tt { $($body:tt)* }) => {
$crate::__declared!($m ['de $($gen)*] ['de $($gen)*] [$case] $ty { $($body)* });
};
($m:ident [ 'de $($gen:tt)* ] $ty:ty { $($body:tt)* }) => {
$crate::__declared!($m ['de $($gen)*] ['de $($gen)*] [_] $ty { $($body)* });
};
($m:ident [ $($gen:tt)* ] $ty:ty as $case:tt { $($body:tt)* }) => {
$crate::__declared!($m ['de, $($gen)*] [$($gen)*] [$case] $ty { $($body)* });
};
($m:ident [ $($gen:tt)* ] $ty:ty { $($body:tt)* }) => {
$crate::__declared!($m ['de, $($gen)*] [$($gen)*] [_] $ty { $($body)* });
};
($m:ident $ty:ty as $case:tt { $($body:tt)* }) => {
$crate::__declared!($m ['de] [] [$case] $ty { $($body)* });
};
($m:ident $ty:ty { $($body:tt)* }) => {
$crate::__declared!($m ['de] [] [_] $ty { $($body)* });
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __declared {
($m:ident [$($rgen:tt)*] [$($wgen:tt)*] [$case:tt] $ty:ty {
$($(#[$req:ident])? $($key:literal =>)? $field:ident $(as $with:ty)? ,)* ..
}) => {
$crate::__case_check!($case);
$crate::__keys_impl!([$($wgen)*] [$case] [partial] $ty {
$($(#[$req])? $($key =>)? $field $(as $with)?),*
});
$crate::$m!([$($rgen)*] [$($wgen)*] [$case] $ty {
$($(#[$req])? $($key =>)? $field $(as $with)?),*
});
};
($m:ident [$($rgen:tt)*] [$($wgen:tt)*] [$case:tt] $ty:ty {
$($(#[$req:ident])? $($key:literal =>)? $field:ident $(as $with:ty)?),* $(,)?
}) => {
$crate::__case_check!($case);
$crate::__keys_impl!([$($wgen)*] [$case] [all] $ty {
$($(#[$req])? $($key =>)? $field $(as $with)?),*
});
$crate::$m!([$($rgen)*] [$($wgen)*] [$case] $ty {
$($(#[$req])? $($key =>)? $field $(as $with)?),*
});
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __both_impls {
([$($rgen:tt)*] [$($wgen:tt)*] [$case:tt] $ty:ty { $($body:tt)* }) => {
$crate::__json_impls!([$($rgen)*] [$($wgen)*] [$case] $ty { $($body)* });
$crate::__beve_impls!([$($rgen)*] [$($wgen)*] [$case] $ty { $($body)* });
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __each_name_once {
($($name:ident),* $(,)?) => {
const _: () = {
$( #[allow(dead_code, non_upper_case_globals)] const $name: () = (); )*
};
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __declares_every_field {
([$($wgen:tt)*] [partial] $ty:ty { $($field:ident),* }) => {};
([$($wgen:tt)*] [all] $ty:ty { $($field:ident),* }) => {
const _: () = {
#[allow(dead_code)]
trait DeclaresEveryField: ::core::marker::Sized {
fn declared() -> Self;
}
impl<$($wgen)*> DeclaresEveryField for $ty {
#[allow(unreachable_code, clippy::empty_loop)]
fn declared() -> Self {
Self { $($field: loop {}),* }
}
}
};
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __is_required {
() => {
false
};
(required) => {
true
};
($other:ident) => {
::core::compile_error!(::core::concat!(
"unrecognized field marker `#[",
::core::stringify!($other),
"]`; the only one is `#[required]`"
))
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __keys_impl {
(
[$($wgen:tt)*] [$case:tt] [$mode:ident] $ty:ty {
$($(#[$req:ident])? $($key:literal =>)? $field:ident $(as $with:ty)?),* $(,)?
}
) => {
$crate::__each_name_once!($($field),*);
$crate::__declares_every_field!([$($wgen)*] [$mode] $ty { $($field),* });
impl<$($wgen)*> $crate::Keys for $ty {
const KEYS: &'static [&'static str] = &[
$( $crate::__json_key!([$case] $($key)? [$field]) ),*
];
const MAP: &'static $crate::KeyMap = &$crate::KeyMap::build(Self::KEYS);
#[allow(unused_assignments, unused_mut)]
const REQUIRED: u64 = {
let mut mask = 0u64;
let mut i = 0u32;
$(
if $crate::__is_required!($($req)?) {
assert!(
i < 64,
"a #[required] field must be one of the first 64 \
declared: the mask that tracks them is a u64"
);
mask |= 1u64 << i;
}
i += 1;
)*
mask
};
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __json_impls {
(
[$($rgen:tt)*] [$($wgen:tt)*] [$case:tt] $ty:ty {
$($(#[$req:ident])? $($key:literal =>)? $field:ident $(as $with:ty)?),* $(,)?
}
) => {
impl<$($rgen)*> $crate::json::ReadObject<'de> for $ty {
#[inline]
#[allow(unused_assignments, unused_variables, unused_mut)]
fn read_field<O: $crate::Options>(
&mut self,
index: usize,
p: &mut $crate::json::Parser<'de, O>,
) -> ::core::result::Result<bool, $crate::ErrorCode> {
let mut i = 0usize;
$(
if index == i {
if !p.match_key($crate::__json_key!([$case] $($key)? [$field])) {
return ::core::result::Result::Ok(false);
}
p.colon()?;
$crate::__json_read_as!(&mut self.$field, p $(, $with)?)?;
return ::core::result::Result::Ok(true);
}
i += 1;
)*
::core::result::Result::Ok(false)
}
}
impl<$($wgen)*> $crate::json::WriteObject for $ty {
#[inline]
fn write_fields<O: $crate::Options>(
&self,
w: &mut $crate::json::Writer<'_, O>,
) {
const {
let _ = <Self as $crate::Keys>::MAP;
};
$( $crate::__write_member!(
w,
$crate::__json_member!([$case] $($key)? [$field]),
&self.$field
$(, $with)?
); )*
}
}
impl<$($rgen)*> $crate::json::Read<'de> for $ty {
#[inline]
fn read<O: $crate::Options>(
&mut self,
p: &mut $crate::json::Parser<'de, O>,
) -> ::core::result::Result<(), $crate::ErrorCode> {
p.read_object(self)
}
}
impl<$($wgen)*> $crate::json::Write for $ty {
#[inline]
fn write<O: $crate::Options>(&self, w: &mut $crate::json::Writer<'_, O>) {
w.write_object(self);
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __beve_impls {
(
[$($rgen:tt)*] [$($wgen:tt)*] [$case:tt] $ty:ty {
$($(#[$req:ident])? $($key:literal =>)? $field:ident $(as $with:ty)?),* $(,)?
}
) => {
impl<$($rgen)*> $crate::beve::ReadObject<'de> for $ty {
#[inline]
#[allow(unused_assignments, unused_variables, unused_mut)]
fn read_field<O: $crate::Options>(
&mut self,
index: usize,
key: &[u8],
r: &mut $crate::beve::Reader<'de, O>,
) -> ::core::result::Result<bool, $crate::ErrorCode> {
let mut i = 0usize;
$(
if index == i {
if key != $crate::__json_key!([$case] $($key)? [$field]).as_bytes() {
return ::core::result::Result::Ok(false);
}
$crate::__beve_read_as!(&mut self.$field, r $(, $with)?)?;
return ::core::result::Result::Ok(true);
}
i += 1;
)*
::core::result::Result::Ok(false)
}
}
impl<$($wgen)*> $crate::beve::WriteObject for $ty {
#[inline]
fn write_fields<O: $crate::Options>(
&self,
w: &mut $crate::beve::Writer<'_, O>,
) {
const {
let _ = <Self as $crate::Keys>::MAP;
};
$( $crate::__write_member!(
w,
$crate::__beve_key_bytes!($crate::__json_key!([$case] $($key)? [$field])),
&self.$field
$(, $with)?
); )*
}
#[inline]
#[allow(unused_mut)]
fn count_fields<O: $crate::Options>(&self) -> usize {
let mut n = 0usize;
$(
n += !(O::SKIP_NULL
&& $crate::__beve_is_null_as!(&self.$field $(, $with)?)) as usize;
)*
n
}
}
impl<$($rgen)*> $crate::beve::Read<'de> for $ty {
#[inline]
fn read<O: $crate::Options>(
&mut self,
r: &mut $crate::beve::Reader<'de, O>,
) -> ::core::result::Result<(), $crate::ErrorCode> {
r.read_object(self)
}
}
impl<$($wgen)*> $crate::beve::Write for $ty {
#[inline]
fn write<O: $crate::Options>(&self, w: &mut $crate::beve::Writer<'_, O>) {
w.write_object(self);
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __json_key {
([$case:tt] $key:literal [$field:ident]) => {
$key
};
([_] [$field:ident]) => {
::core::stringify!($field)
};
([$case:tt] [$field:ident]) => {
$crate::__case_apply!($case, ::core::stringify!($field))
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __json_member {
($($key:tt)*) => {{
const KEY: &str = $crate::__json_key!($($key)*);
const N: usize = KEY.len() + 3;
const PREFIX: [u8; N] = $crate::json::quoted_key::<{ N }>(KEY);
const OUT: &str = $crate::case::as_str(&PREFIX);
OUT
}};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __beve_key_bytes {
($key:expr) => {{
const KEY: &str = $key;
const N: usize = $crate::beve::header::key_len(KEY);
const ENCODED: [u8; N] = $crate::beve::header::encode_key::<{ N }>(KEY);
&ENCODED
}};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __case_apply {
($case:literal, $name:expr) => {{
const NAME: &str = $name;
const RULE: &str = $case;
const STYLE: $crate::case::Style = $crate::case::style(RULE);
const N: usize = $crate::case::cased_len(NAME, STYLE);
const CASED: [u8; N] = $crate::case::cased::<{ N }>(NAME, STYLE);
const OUT: &str = $crate::case::as_str(&CASED);
OUT
}};
($other:tt, $name:expr) => {
$name
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __case_check {
(_) => {};
($case:literal) => {};
($other:tt) => {
::core::compile_error!(::core::concat!(
"structio: `",
::core::stringify!($other),
"` is not a case rule; a rule is written as a string, as in \
`object!(Root as \"camelCase\" { .. })`"
));
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __json_read_as {
($place:expr, $p:ident, $with:ty) => {
<$with as $crate::json::ReadAs<'_, _>>::read($place, $p)
};
($place:expr, $p:ident) => {
$crate::json::Read::read($place, $p)
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __write_member {
($w:ident, $key:expr, $place:expr, $with:ty) => {
$w.member_with::<$with, _>($key, $place)
};
($w:ident, $key:expr, $place:expr) => {
$w.member($key, $place)
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __beve_read_as {
($place:expr, $r:ident, $with:ty) => {
<$with as $crate::beve::ReadAs<'_, _>>::read($place, $r)
};
($place:expr, $r:ident) => {
$crate::beve::Read::read($place, $r)
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __beve_is_null_as {
($place:expr, $with:ty) => {
<$with as $crate::beve::WriteAs<_>>::is_null($place)
};
($place:expr) => {
$crate::beve::Write::is_null($place)
};
}
#[macro_export]
macro_rules! array {
($($t:tt)*) => { $crate::__declare_array!(__both_array_impls $($t)*); };
}
#[macro_export]
macro_rules! json_array {
($($t:tt)*) => { $crate::__declare_array!(__json_array_impls $($t)*); };
}
#[macro_export]
macro_rules! beve_array {
($($t:tt)*) => { $crate::__declare_array!(__beve_array_impls $($t)*); };
}
#[doc(hidden)]
#[macro_export]
macro_rules! __declare_array {
($m:ident [ 'de $($gen:tt)* ] $ty:ty as $case:tt [ $($body:tt)* ]) => {
$crate::__no_array_case!();
};
($m:ident [ 'de $($gen:tt)* ] $ty:ty [ $($body:tt)* ]) => {
$crate::__declared_array!($m ['de $($gen)*] ['de $($gen)*] $ty [ $($body)* ]);
};
($m:ident [ $($gen:tt)* ] $ty:ty as $case:tt [ $($body:tt)* ]) => {
$crate::__no_array_case!();
};
($m:ident [ $($gen:tt)* ] $ty:ty [ $($body:tt)* ]) => {
$crate::__declared_array!($m ['de, $($gen)*] [$($gen)*] $ty [ $($body)* ]);
};
($m:ident $ty:ty as $case:tt [ $($body:tt)* ]) => {
$crate::__no_array_case!();
};
($m:ident $ty:ty [ $($body:tt)* ]) => {
$crate::__declared_array!($m ['de] [] $ty [ $($body)* ]);
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __no_array_case {
() => {
::core::compile_error!(
"structio: a positional struct has no keys, so a case rule has nothing to \
convert. Case rules belong on `object!`, `unit_enum!` and `tagged_enum!`."
);
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __both_array_impls {
([$($rgen:tt)*] [$($wgen:tt)*] $ty:ty [ $($body:tt)* ]) => {
$crate::__json_array_impls!([$($rgen)*] [$($wgen)*] $ty [ $($body)* ]);
$crate::__beve_array_impls!([$($rgen)*] [$($wgen)*] $ty [ $($body)* ]);
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __declared_array {
($m:ident [$($rgen:tt)*] [$($wgen:tt)*] $ty:ty [ $elem:ty ; $($field:ident ,)* .. ]) => {
$crate::__elements_impl!([$($wgen)*] [partial] $ty [ $elem ; $($field),* ]);
$crate::$m!([$($rgen)*] [$($wgen)*] $ty [ $elem ; $($field),* ]);
};
($m:ident [$($rgen:tt)*] [$($wgen:tt)*] $ty:ty [ $elem:ty ; $($field:ident),* $(,)? ]) => {
$crate::__elements_impl!([$($wgen)*] [all] $ty [ $elem ; $($field),* ]);
$crate::$m!([$($rgen)*] [$($wgen)*] $ty [ $elem ; $($field),* ]);
};
($m:ident [$($rgen:tt)*] [$($wgen:tt)*] $ty:ty [ $($field:ident ,)* .. ]) => {
$crate::__elements_impl!([$($wgen)*] [partial] $ty [ $($field),* ]);
$crate::$m!([$($rgen)*] [$($wgen)*] $ty [ $($field),* ]);
};
($m:ident [$($rgen:tt)*] [$($wgen:tt)*] $ty:ty [ $($field:ident),* $(,)? ]) => {
$crate::__elements_impl!([$($wgen)*] [all] $ty [ $($field),* ]);
$crate::$m!([$($rgen)*] [$($wgen)*] $ty [ $($field),* ]);
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __elements_impl {
([$($wgen:tt)*] [$mode:ident] $ty:ty [ $elem:ty ; $($field:ident),* $(,)? ]) => {
$crate::__elements_impl!([$($wgen)*] [$mode] $ty [ $($field),* ]);
const _: () = {
#[allow(dead_code)]
fn every_field_is_the_element_type<$($wgen)*>(v: &$ty) {
$( let _: &$elem = &v.$field; )*
}
};
};
([$($wgen:tt)*] [$mode:ident] $ty:ty [ $($field:ident),* $(,)? ]) => {
$crate::__each_name_once!($($field),*);
$crate::__declares_every_field!([$($wgen)*] [$mode] $ty { $($field),* });
impl<$($wgen)*> $crate::Elements for $ty {
const LEN: usize =
<[&'static str]>::len(&[$( ::core::stringify!($field) ),*]);
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __json_array_impls {
([$($rgen:tt)*] [$($wgen:tt)*] $ty:ty [ $elem:ty ; $($field:ident),* $(,)? ]) => {
$crate::__json_array_impls!([$($rgen)*] [$($wgen)*] $ty [ $($field),* ]);
};
([$($rgen:tt)*] [$($wgen:tt)*] $ty:ty [ $($field:ident),* $(,)? ]) => {
impl<$($rgen)*> $crate::json::ReadArray<'de> for $ty {
#[inline]
#[allow(unused_assignments, unused_variables, unused_mut)]
fn read_element<O: $crate::Options>(
&mut self,
index: usize,
p: &mut $crate::json::Parser<'de, O>,
) -> ::core::result::Result<(), $crate::ErrorCode> {
let mut i = 0usize;
$(
if index == i {
return $crate::json::Read::read(&mut self.$field, p);
}
i += 1;
)*
::core::result::Result::Err($crate::ErrorCode::ArrayLengthMismatch)
}
}
impl<$($wgen)*> $crate::json::WriteArray for $ty {
#[inline]
fn write_elements<O: $crate::Options>(
&self,
w: &mut $crate::json::Writer<'_, O>,
) {
$( w.element(&self.$field); )*
}
}
impl<$($rgen)*> $crate::json::Read<'de> for $ty {
#[inline]
fn read<O: $crate::Options>(
&mut self,
p: &mut $crate::json::Parser<'de, O>,
) -> ::core::result::Result<(), $crate::ErrorCode> {
p.read_array(self)
}
}
impl<$($wgen)*> $crate::json::Write for $ty {
#[inline]
fn write<O: $crate::Options>(&self, w: &mut $crate::json::Writer<'_, O>) {
w.write_array(self);
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __beve_array_impls {
([$($rgen:tt)*] [$($wgen:tt)*] $ty:ty [ $elem:ty ; $($field:ident),* $(,)? ]) => {
$crate::__beve_array_body!([$($rgen)*] [$($wgen)*] $ty [ $($field),* ] {
const ARRAY: ::core::option::Option<&'static [u8]> =
<$elem as $crate::beve::Write>::ARRAY;
#[inline]
fn write_payload<O: $crate::Options>(
&self,
w: &mut $crate::beve::Writer<'_, O>,
) {
<$elem as $crate::beve::Write>::write_payload(&[$( self.$field ),*], w);
}
});
};
([$($rgen:tt)*] [$($wgen:tt)*] $ty:ty [ $($field:ident),* $(,)? ]) => {
$crate::__beve_array_body!([$($rgen)*] [$($wgen)*] $ty [ $($field),* ] {});
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __beve_array_body {
(
[$($rgen:tt)*] [$($wgen:tt)*] $ty:ty [ $($field:ident),* ] { $($typed:tt)* }
) => {
impl<$($rgen)*> $crate::beve::ReadArray<'de> for $ty {
#[inline]
#[allow(unused_assignments, unused_variables, unused_mut)]
fn read_element<O: $crate::Options>(
&mut self,
index: usize,
r: &mut $crate::beve::Reader<'de, O>,
) -> ::core::result::Result<(), $crate::ErrorCode> {
let mut i = 0usize;
$(
if index == i {
return $crate::beve::Read::read(&mut self.$field, r);
}
i += 1;
)*
::core::result::Result::Err($crate::ErrorCode::ArrayLengthMismatch)
}
}
impl<$($wgen)*> $crate::beve::WriteArray for $ty {
#[inline]
fn write_elements<O: $crate::Options>(
&self,
w: &mut $crate::beve::Writer<'_, O>,
) {
$( w.element(&self.$field); )*
}
$($typed)*
}
impl<$($rgen)*> $crate::beve::Read<'de> for $ty {
#[inline]
fn read<O: $crate::Options>(
&mut self,
r: &mut $crate::beve::Reader<'de, O>,
) -> ::core::result::Result<(), $crate::ErrorCode> {
r.read_array(self)
}
}
impl<$($wgen)*> $crate::beve::Write for $ty {
#[inline]
fn write<O: $crate::Options>(&self, w: &mut $crate::beve::Writer<'_, O>) {
w.write_array(self);
}
}
};
}
#[macro_export]
macro_rules! unit_enum {
([$($gen:tt)*] $ty:ty as $case:tt { $($($name:literal =>)? $variant:ident),* $(,)? }) => {
$crate::__declare_enum!(
__both_unit_enum_impls [$($gen)*] $ty as $case { $($($name =>)? $variant),* }
);
};
([$($gen:tt)*] $ty:ty { $($($name:literal =>)? $variant:ident),* $(,)? }) => {
$crate::__declare_enum!(
__both_unit_enum_impls [$($gen)*] $ty { $($($name =>)? $variant),* }
);
};
($ty:ty as $case:tt { $($($name:literal =>)? $variant:ident),* $(,)? }) => {
$crate::__declare_enum!(
__both_unit_enum_impls $ty as $case { $($($name =>)? $variant),* }
);
};
($ty:ty { $($($name:literal =>)? $variant:ident),* $(,)? }) => {
$crate::__declare_enum!(
__both_unit_enum_impls $ty { $($($name =>)? $variant),* }
);
};
($($rest:tt)*) => {
::core::compile_error!(
"`unit_enum!` takes a type and a brace-delimited list of variant \
names, each optionally renamed with `\"name\" => Variant`. A \
variant that carries a value, written `Variant(_)`, belongs to \
`tagged_enum!` instead."
);
};
}
#[macro_export]
macro_rules! tagged_enum {
($($t:tt)*) => { $crate::__declare_enum!(__both_enum_impls $($t)*); };
}
#[macro_export]
macro_rules! json_tagged_enum {
($($t:tt)*) => { $crate::__declare_enum!(__json_enum_impls $($t)*); };
}
#[macro_export]
macro_rules! beve_tagged_enum {
($($t:tt)*) => { $crate::__declare_enum!(__beve_enum_impls $($t)*); };
}
#[doc(hidden)]
#[macro_export]
macro_rules! __declare_enum {
($m:ident [ 'de $($gen:tt)* ] $ty:ty as $case:tt { $($body:tt)* }) => {
$crate::__declared_enum!($m ['de $($gen)*] ['de $($gen)*] [$case] $ty { $($body)* });
};
($m:ident [ 'de $($gen:tt)* ] $ty:ty { $($body:tt)* }) => {
$crate::__declared_enum!($m ['de $($gen)*] ['de $($gen)*] [_] $ty { $($body)* });
};
($m:ident [ $($gen:tt)* ] $ty:ty as $case:tt { $($body:tt)* }) => {
$crate::__declared_enum!($m ['de, $($gen)*] [$($gen)*] [$case] $ty { $($body)* });
};
($m:ident [ $($gen:tt)* ] $ty:ty { $($body:tt)* }) => {
$crate::__declared_enum!($m ['de, $($gen)*] [$($gen)*] [_] $ty { $($body)* });
};
($m:ident $ty:ty as $case:tt { $($body:tt)* }) => {
$crate::__declared_enum!($m ['de] [] [$case] $ty { $($body)* });
};
($m:ident $ty:ty { $($body:tt)* }) => {
$crate::__declared_enum!($m ['de] [] [_] $ty { $($body)* });
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __declared_enum {
($m:ident [$($rgen:tt)*] [$($wgen:tt)*] [$case:tt] $ty:ty { $($body:tt)* }) => {
$crate::__case_check!($case);
$crate::__variants_impl!([$($wgen)*] [$case] $ty { $($body)* });
$crate::$m!([$($rgen)*] [$($wgen)*] [$case] $ty { $($body)* });
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __both_unit_enum_impls {
([$($rgen:tt)*] [$($wgen:tt)*] [$case:tt] $ty:ty { $($body:tt)* }) => {
$crate::__json_enum_impls!([$($rgen)*] [$($wgen)*] [$case] $ty { $($body)* });
$crate::__beve_unit_enum_impls!([$($rgen)*] [$($wgen)*] [$case] $ty { $($body)* });
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __both_enum_impls {
([$($rgen:tt)*] [$($wgen:tt)*] [$case:tt] $ty:ty { $($body:tt)* }) => {
$crate::__json_enum_impls!([$($rgen)*] [$($wgen)*] [$case] $ty { $($body)* });
$crate::__beve_enum_impls!([$($rgen)*] [$($wgen)*] [$case] $ty { $($body)* });
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __payload_is_wildcard {
() => {};
(_) => {};
($($other:tt)*) => {
::core::compile_error!(
"structio: a variant payload is written `(_)`, and carries no options of its own. \
Field adapters (`as ...`) are supported on `object!` fields, not on enum payloads."
);
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __variants_impl {
(
[$($wgen:tt)*] [$case:tt] $ty:ty {
$($($name:literal =>)? $variant:ident $(($($payload:tt)*))?),* $(,)?
}
) => {
$crate::__each_name_once!($($variant),*);
$( $crate::__payload_is_wildcard!($($($payload)*)?); )*
impl<$($wgen)*> $crate::Variants for $ty {
const VARIANTS: &'static [&'static str] = &[
$( $crate::__json_key!([$case] $($name)? [$variant]) ),*
];
const MAP: &'static $crate::KeyMap = &$crate::KeyMap::build(Self::VARIANTS);
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __json_enum_impls {
(
[$($rgen:tt)*] [$($wgen:tt)*] [$case:tt] $ty:ty {
$($($name:literal =>)? $variant:ident $(($($payload:tt)*))?),* $(,)?
}
) => {
impl<$($rgen)*> $crate::json::ReadEnum<'de> for $ty {
#[inline]
#[allow(unused_assignments, unused_variables, unused_mut)]
fn read_name<O: $crate::Options>(
&mut self,
index: usize,
p: &mut $crate::json::Parser<'de, O>,
) -> ::core::result::Result<bool, $crate::ErrorCode> {
let mut i = 0usize;
$(
if index == i {
return $crate::__json_read_name!(
self, p,
$crate::__json_key!([$case] $($name)? [$variant]),
$variant $(($($payload)*))?
);
}
i += 1;
)*
::core::result::Result::Ok(false)
}
#[inline]
#[allow(unused_assignments, unused_variables, unused_mut, unreachable_patterns)]
fn read_payload<O: $crate::Options>(
&mut self,
index: usize,
p: &mut $crate::json::Parser<'de, O>,
) -> ::core::result::Result<bool, $crate::ErrorCode> {
let mut i = 0usize;
$(
if index == i {
return $crate::__json_read_payload!(
self, p,
$crate::__json_key!([$case] $($name)? [$variant]),
$variant $(($($payload)*))?
);
}
i += 1;
)*
::core::result::Result::Ok(false)
}
}
impl<$($rgen)*> $crate::json::Read<'de> for $ty {
#[inline]
fn read<O: $crate::Options>(
&mut self,
p: &mut $crate::json::Parser<'de, O>,
) -> ::core::result::Result<(), $crate::ErrorCode> {
p.read_enum(self)
}
}
impl<$($wgen)*> $crate::json::Write for $ty {
#[inline]
#[allow(irrefutable_let_patterns)]
fn write<O: $crate::Options>(&self, w: &mut $crate::json::Writer<'_, O>) {
const {
let _ = <Self as $crate::Variants>::MAP;
};
$(
$crate::__write_variant!(
self, w,
$crate::__json_key!([$case] $($name)? [$variant]),
$crate::__json_member!([$case] $($name)? [$variant]),
$variant $(($($payload)*))?
);
)*
match self { $( Self::$variant { .. } => {} ),* }
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __json_read_name {
($self:ident, $p:ident, $name:expr, $variant:ident) => {
if $p.match_key($name) {
*$self = Self::$variant;
::core::result::Result::Ok(true)
} else {
::core::result::Result::Ok(false)
}
};
($self:ident, $p:ident, $name:expr, $variant:ident ($($payload:tt)*)) => {
if $p.match_key($name) {
::core::result::Result::Err($crate::ErrorCode::ExpectedBrace)
} else {
::core::result::Result::Ok(false)
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __json_read_payload {
($self:ident, $p:ident, $name:expr, $variant:ident) => {
if $p.match_key($name) {
$p.colon()?;
if $p.try_null()? {
*$self = Self::$variant;
::core::result::Result::Ok(true)
} else {
::core::result::Result::Err($crate::ErrorCode::ExpectedNull)
}
} else {
::core::result::Result::Ok(false)
}
};
($self:ident, $p:ident, $name:expr, $variant:ident ($($payload:tt)*)) => {
if $p.match_key($name) {
$p.colon()?;
match $self {
Self::$variant(v) => {
$crate::json::Read::read(v, $p)?;
}
_ => {
let mut value = ::core::default::Default::default();
$crate::json::Read::read(&mut value, $p)?;
*$self = Self::$variant(value);
}
}
::core::result::Result::Ok(true)
} else {
::core::result::Result::Ok(false)
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __write_variant {
($self:ident, $w:ident, $name:expr, $key:expr, $variant:ident) => {
if let Self::$variant = $self {
$w.write_str($name);
return;
}
};
($self:ident, $w:ident, $name:expr, $key:expr, $variant:ident ($($payload:tt)*)) => {
if let Self::$variant(v) = $self {
$w.write_tagged($key, v);
return;
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __beve_enum_impls {
(
[$($rgen:tt)*] [$($wgen:tt)*] [$case:tt] $ty:ty {
$($($name:literal =>)? $variant:ident $(($($payload:tt)*))?),* $(,)?
}
) => {
$crate::__beve_enum_body!([$($rgen)*] [$($wgen)*] [$case] $ty {
$($($name =>)? $variant $(($($payload)*))?),*
} {});
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __beve_unit_enum_impls {
(
[$($rgen:tt)*] [$($wgen:tt)*] [$case:tt] $ty:ty {
$($($name:literal =>)? $variant:ident),* $(,)?
}
) => {
$crate::__beve_enum_body!([$($rgen)*] [$($wgen)*] [$case] $ty {
$($($name =>)? $variant),*
} {
const ARRAY: ::core::option::Option<&'static [u8]> =
::core::option::Option::Some(&[$crate::beve::header::STRING_ARRAY]);
#[inline]
fn write_payload<O: $crate::Options>(
items: &[Self],
w: &mut $crate::beve::Writer<'_, O>,
) where
Self: ::core::marker::Sized,
{
for item in items {
w.write_str_body(match item {
$( Self::$variant => $crate::__json_key!([$case] $($name)? [$variant]) ),*
});
}
}
});
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __beve_enum_body {
(
[$($rgen:tt)*] [$($wgen:tt)*] [$case:tt] $ty:ty {
$($($name:literal =>)? $variant:ident $(($($payload:tt)*))?),* $(,)?
} { $($typed:tt)* }
) => {
impl<$($rgen)*> $crate::beve::ReadEnum<'de> for $ty {
#[inline]
#[allow(unused_assignments, unused_variables, unused_mut)]
fn read_name(
&mut self,
index: usize,
name: &[u8],
) -> ::core::result::Result<bool, $crate::ErrorCode> {
let mut i = 0usize;
$(
if index == i {
return $crate::__beve_read_name!(
self, name,
$crate::__json_key!([$case] $($name)? [$variant]),
$variant $(($($payload)*))?
);
}
i += 1;
)*
::core::result::Result::Ok(false)
}
#[inline]
#[allow(unused_assignments, unused_variables, unused_mut, unreachable_patterns)]
fn read_payload<O: $crate::Options>(
&mut self,
index: usize,
name: &[u8],
r: &mut $crate::beve::Reader<'de, O>,
) -> ::core::result::Result<bool, $crate::ErrorCode> {
let mut i = 0usize;
$(
if index == i {
return $crate::__beve_read_payload!(
self, name, r,
$crate::__json_key!([$case] $($name)? [$variant]),
$variant $(($($payload)*))?
);
}
i += 1;
)*
::core::result::Result::Ok(false)
}
}
impl<$($rgen)*> $crate::beve::Read<'de> for $ty {
#[inline]
fn read<O: $crate::Options>(
&mut self,
r: &mut $crate::beve::Reader<'de, O>,
) -> ::core::result::Result<(), $crate::ErrorCode> {
r.read_enum(self)
}
}
impl<$($wgen)*> $crate::beve::Write for $ty {
#[inline]
#[allow(irrefutable_let_patterns)]
fn write<O: $crate::Options>(&self, w: &mut $crate::beve::Writer<'_, O>) {
const {
let _ = <Self as $crate::Variants>::MAP;
};
$(
$crate::__write_variant!(
self, w,
$crate::__json_key!([$case] $($name)? [$variant]),
$crate::__beve_key_bytes!($crate::__json_key!([$case] $($name)? [$variant])),
$variant $(($($payload)*))?
);
)*
match self { $( Self::$variant { .. } => {} ),* }
}
$($typed)*
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __beve_read_name {
($self:ident, $key:ident, $name:expr, $variant:ident) => {
if $key == $name.as_bytes() {
*$self = Self::$variant;
::core::result::Result::Ok(true)
} else {
::core::result::Result::Ok(false)
}
};
($self:ident, $key:ident, $name:expr, $variant:ident ($($payload:tt)*)) => {
if $key == $name.as_bytes() {
::core::result::Result::Err($crate::ErrorCode::ExpectedObject)
} else {
::core::result::Result::Ok(false)
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __beve_read_payload {
($self:ident, $key:ident, $r:ident, $name:expr, $variant:ident) => {
if $key == $name.as_bytes() {
if $r.try_null()? {
*$self = Self::$variant;
::core::result::Result::Ok(true)
} else {
::core::result::Result::Err($crate::ErrorCode::ExpectedNull)
}
} else {
::core::result::Result::Ok(false)
}
};
($self:ident, $key:ident, $r:ident, $name:expr, $variant:ident ($($payload:tt)*)) => {
if $key == $name.as_bytes() {
match $self {
Self::$variant(v) => {
$crate::beve::Read::read(v, $r)?;
}
_ => {
let mut value = ::core::default::Default::default();
$crate::beve::Read::read(&mut value, $r)?;
*$self = Self::$variant(value);
}
}
::core::result::Result::Ok(true)
} else {
::core::result::Result::Ok(false)
}
};
}