#[macro_export]
macro_rules! manifest {
($manifest_name:ident:) => {
#[derive(Default)]
pub struct $manifest_name;
};
// Multiple items case with manifest name - generate implementations with incrementing indices
($manifest_name:ident: $($ty:ty),+ $(,)?) => {
$crate::paste! {
#[derive(Default)]
pub struct $manifest_name {
$(
[<last_ $ty:snake>]: ::core::option::Option<<$ty as $crate::DatabaseEntry>::Key>,
)*
}
}
$crate::scope_impl_with_index!($manifest_name, 0; $($ty),+);
impl $crate::Manifest for $manifest_name {
fn members() -> &'static [u8] {
&$crate::generate_member_scopes!(0; $($ty),+)
}
fn load<S: $crate::Storage>(&mut self, db: &mut $crate::Database<S, Self>) -> ::core::result::Result<(), $crate::DatabaseError<S>> {
$crate::paste! {
$(
self.[<last_ $ty:snake>] = ::core::option::Option::Some(db.last_id()?);
)*
}
::core::result::Result::Ok(())
}
}
};
($($ty:ty),+ $(,)?) => {
compile_error!("manifest! macro requires a manifest name followed by a colon. Use: manifest![ManifestName: Type1, Type2, ...]");
};
($ty:ty) => {
compile_error!("manifest! macro requires a manifest name followed by a colon. Use: manifest![ManifestName: Type1, Type2, ...]");
};
}
#[macro_export]
macro_rules! generate_member_scopes {
($index:expr; $($ty:ty),+) => {
{
[
$(<$ty as $crate::Scope>::SCOPE),+
]
}
};
}
#[macro_export]
macro_rules! scope_impl_with_index {
($manifest_name:ident, $index:expr;) => {};
($manifest_name:ident, $index:expr; $ty:ty) => {
impl $crate::Scope for $ty {
const SCOPE: u8 = $index;
type Manifest = $manifest_name;
}
impl $crate::Manifests<$ty> for $manifest_name {
fn last(&mut self) -> &mut ::core::option::Option<<$ty as $crate::DatabaseEntry>::Key> {
$crate::paste! {
&mut self.[<last_ $ty:snake>]
}
}
}
};
($manifest_name:ident, $index:expr; $ty:ty, $($rest:ty),+) => {
impl $crate::Scope for $ty {
const SCOPE: u8 = $index;
type Manifest = $manifest_name;
}
impl $crate::Manifests<$ty> for $manifest_name {
fn last(&mut self) -> &mut ::core::option::Option<<$ty as $crate::DatabaseEntry>::Key> {
$crate::paste! {
&mut self.[<last_ $ty:snake>]
}
}
}
$crate::scope_impl_with_index!($manifest_name, $index + 1; $($rest),+);
};
}