mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-08 19:34:27 +00:00
Revised generate_enum_property_option to be closer to an eventual derive.
This commit is contained in:
@@ -214,9 +214,17 @@ generate_enum_property_mod!(
|
||||
);
|
||||
|
||||
util::generate_enum_property_option!(
|
||||
pub struct MaybeArrowColor (ArrowColor ) => 0,
|
||||
pub struct MaybeCrossMoveEffect (CrossMoveEffect ) => 0,
|
||||
pub struct MaybeDigimonProperty (DigimonProperty ) => 0,
|
||||
#[derive(BytesProxySentinel)]
|
||||
#[bytes_proxy_sentinel(value = 0)]
|
||||
pub struct MaybeArrowColor(Option<ArrowColor>);
|
||||
|
||||
#[derive(BytesProxySentinel)]
|
||||
#[bytes_proxy_sentinel(value = 0)]
|
||||
pub struct MaybeCrossMoveEffect(Option<CrossMoveEffect>);
|
||||
|
||||
#[derive(BytesProxySentinel)]
|
||||
#[bytes_proxy_sentinel(value = 0)]
|
||||
pub struct MaybeDigimonProperty(Option<DigimonProperty>);
|
||||
);
|
||||
|
||||
// Complex
|
||||
|
||||
@@ -57,9 +57,17 @@ generate_enum_property_mod! {
|
||||
}
|
||||
|
||||
generate_enum_property_option!(
|
||||
pub struct MaybeCity (City ) => 0,
|
||||
pub struct MaybeArmorEvo(ArmorEvo) => 0,
|
||||
pub struct MaybeMusic (Music ) => 0,
|
||||
#[derive(BytesProxySentinel)]
|
||||
#[bytes_proxy_sentinel(value = 0)]
|
||||
pub struct MaybeCity(Option<City>);
|
||||
|
||||
#[derive(BytesProxySentinel)]
|
||||
#[bytes_proxy_sentinel(value = 0)]
|
||||
pub struct MaybeArmorEvo(Option<ArmorEvo>);
|
||||
|
||||
#[derive(BytesProxySentinel)]
|
||||
#[bytes_proxy_sentinel(value = 0)]
|
||||
pub struct MaybeMusic(Option<Music>);
|
||||
);
|
||||
|
||||
// Modules
|
||||
|
||||
@@ -133,47 +133,49 @@ macro_rules! generate_enum_property_mod
|
||||
/// is the first argument of this macro and an enum.
|
||||
///
|
||||
/// This is done by supplying a sentinel value which is read/written as `None`.
|
||||
pub macro generate_enum_property_option {
|
||||
(
|
||||
$( $struct_vis:vis struct $struct_name:ident ( $enum_vis:vis $enum_name:ty ) => $sentinel_value:literal ),* $(,)?
|
||||
) => {
|
||||
$(
|
||||
#[repr(transparent)]
|
||||
#[derive(derive_more::From, derive_more::Into)]
|
||||
$struct_vis struct $struct_name( $enum_vis Option<$enum_name> );
|
||||
pub macro generate_enum_property_option (
|
||||
$(
|
||||
#[derive(BytesProxySentinel)]
|
||||
#[bytes_proxy_sentinel(value = $sentinel_value:literal)]
|
||||
$struct_vis:vis struct $struct_name:ident ( $enum_vis:vis Option<$enum_name:ty> );
|
||||
)*
|
||||
) {
|
||||
$(
|
||||
#[repr(transparent)]
|
||||
#[derive(derive_more::From, derive_more::Into)]
|
||||
$struct_vis struct $struct_name( $enum_vis Option<$enum_name> );
|
||||
|
||||
impl<'a> From<&'a Option<$enum_name>> for &'a $struct_name {
|
||||
#[allow(clippy::as_conversions)] // We need `as` to make pointer casts
|
||||
fn from(opt: &'a Option<$enum_name>) -> Self {
|
||||
// SAFETY: We're `repr(transparent)`, so this cast is safe
|
||||
unsafe { &*(opt as *const Option<$enum_name> as *const $struct_name) }
|
||||
impl<'a> From<&'a Option<$enum_name>> for &'a $struct_name {
|
||||
#[allow(clippy::as_conversions)] // We need `as` to make pointer casts
|
||||
fn from(opt: &'a Option<$enum_name>) -> Self {
|
||||
// SAFETY: We're `repr(transparent)`, so this cast is safe
|
||||
unsafe { &*(opt as *const Option<$enum_name> as *const $struct_name) }
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::diverging_sub_expression)] // Errors might be `!`
|
||||
impl ::dcb_bytes::Bytes for $struct_name {
|
||||
type ByteArray = <$enum_name as ::dcb_bytes::Bytes>::ByteArray;
|
||||
|
||||
type FromError = <$enum_name as ::dcb_bytes::Bytes>::FromError;
|
||||
fn from_bytes(bytes: &Self::ByteArray) -> Result<Self, Self::FromError>
|
||||
{
|
||||
match bytes {
|
||||
$sentinel_value => Ok( Self(None) ),
|
||||
_ => Ok( Self(Some( ::dcb_bytes::Bytes::from_bytes(bytes)? )) ),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::diverging_sub_expression)] // Errors might be `!`
|
||||
impl ::dcb_bytes::Bytes for $struct_name {
|
||||
type ByteArray = <$enum_name as ::dcb_bytes::Bytes>::ByteArray;
|
||||
|
||||
type FromError = <$enum_name as ::dcb_bytes::Bytes>::FromError;
|
||||
fn from_bytes(bytes: &Self::ByteArray) -> Result<Self, Self::FromError>
|
||||
{
|
||||
match bytes {
|
||||
$sentinel_value => Ok( Self(None) ),
|
||||
_ => Ok( Self(Some( ::dcb_bytes::Bytes::from_bytes(bytes)? )) ),
|
||||
}
|
||||
type ToError = <$enum_name as ::dcb_bytes::Bytes>::ToError;
|
||||
fn to_bytes(&self, bytes: &mut Self::ByteArray) -> Result<(), Self::ToError>
|
||||
{
|
||||
match &self.0 {
|
||||
Some(value) => ::dcb_bytes::Bytes::to_bytes(value, bytes)?,
|
||||
None => *bytes = $sentinel_value,
|
||||
}
|
||||
|
||||
type ToError = <$enum_name as ::dcb_bytes::Bytes>::ToError;
|
||||
fn to_bytes(&self, bytes: &mut Self::ByteArray) -> Result<(), Self::ToError>
|
||||
{
|
||||
match &self.0 {
|
||||
Some(value) => ::dcb_bytes::Bytes::to_bytes(value, bytes)?,
|
||||
None => *bytes = $sentinel_value,
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user