mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-09 03:40:23 +00:00
Now using ref-cast for casting between repr(transparent) references instead of a From hack.
This commit is contained in:
@@ -24,6 +24,7 @@ serde = { version = "1.0", features = ["derive"] }
|
||||
# Derives
|
||||
derive_more = "0.99"
|
||||
thiserror = "1.0"
|
||||
ref-cast = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ use crate::{
|
||||
};
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use dcb_bytes::Bytes;
|
||||
use ref_cast::RefCast;
|
||||
|
||||
// TODO: Remove these
|
||||
/// Name alias for [`Digimon`]
|
||||
@@ -240,28 +241,28 @@ impl Bytes for Digimon {
|
||||
self.move_cross.to_bytes(bytes.move_cross).into_ok();
|
||||
|
||||
// Effects
|
||||
<&MaybeEffectCondition>::from(&self.effect_conditions[0])
|
||||
MaybeEffectCondition::ref_cast(&self.effect_conditions[0])
|
||||
.to_bytes(bytes.condition_first)
|
||||
.into_ok();
|
||||
<&MaybeEffectCondition>::from(&self.effect_conditions[1])
|
||||
MaybeEffectCondition::ref_cast(&self.effect_conditions[1])
|
||||
.to_bytes(bytes.condition_second)
|
||||
.into_ok();
|
||||
|
||||
<&MaybeEffect>::from(&self.effects[0])
|
||||
MaybeEffect::ref_cast(&self.effects[0])
|
||||
.to_bytes(bytes.effect_first)
|
||||
.map_err(ToBytesError::EffectFirst)?;
|
||||
<&MaybeEffect>::from(&self.effects[1])
|
||||
MaybeEffect::ref_cast(&self.effects[1])
|
||||
.to_bytes(bytes.effect_second)
|
||||
.map_err(ToBytesError::EffectSecond)?;
|
||||
<&MaybeEffect>::from(&self.effects[2])
|
||||
MaybeEffect::ref_cast(&self.effects[2])
|
||||
.to_bytes(bytes.effect_third)
|
||||
.map_err(ToBytesError::EffectThird)?;
|
||||
|
||||
<&MaybeCrossMoveEffect>::from(&self.cross_move_effect)
|
||||
MaybeCrossMoveEffect::ref_cast(&self.cross_move_effect)
|
||||
.to_bytes(bytes.cross_move_effect)
|
||||
.into_ok();
|
||||
|
||||
<&MaybeArrowColor>::from(&self.effect_arrow_color)
|
||||
MaybeArrowColor::ref_cast(&self.effect_arrow_color)
|
||||
.to_bytes(bytes.effect_arrow_color)
|
||||
.into_ok();
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ use crate::{
|
||||
};
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use dcb_bytes::Bytes;
|
||||
use ref_cast::RefCast;
|
||||
|
||||
// TODO: Remove these
|
||||
/// Name alias for [`Digimon`]
|
||||
@@ -196,24 +197,24 @@ impl Bytes for Item {
|
||||
bytes.name.write_string(&self.name);
|
||||
|
||||
// Effects
|
||||
<&MaybeEffectCondition>::from(&self.effect_conditions[0])
|
||||
MaybeEffectCondition::ref_cast(&self.effect_conditions[0])
|
||||
.to_bytes(bytes.condition_first)
|
||||
.into_ok();
|
||||
<&MaybeEffectCondition>::from(&self.effect_conditions[1])
|
||||
MaybeEffectCondition::ref_cast(&self.effect_conditions[1])
|
||||
.to_bytes(bytes.condition_second)
|
||||
.into_ok();
|
||||
|
||||
<&MaybeEffect>::from(&self.effects[0])
|
||||
MaybeEffect::ref_cast(&self.effects[0])
|
||||
.to_bytes(bytes.effect_first)
|
||||
.map_err(ToBytesError::EffectFirst)?;
|
||||
<&MaybeEffect>::from(&self.effects[1])
|
||||
MaybeEffect::ref_cast(&self.effects[1])
|
||||
.to_bytes(bytes.effect_second)
|
||||
.map_err(ToBytesError::EffectSecond)?;
|
||||
<&MaybeEffect>::from(&self.effects[2])
|
||||
MaybeEffect::ref_cast(&self.effects[2])
|
||||
.to_bytes(bytes.effect_third)
|
||||
.map_err(ToBytesError::EffectThird)?;
|
||||
|
||||
<&MaybeArrowColor>::from(&self.effect_arrow_color)
|
||||
MaybeArrowColor::ref_cast(&self.effect_arrow_color)
|
||||
.to_bytes(bytes.effect_arrow_color)
|
||||
.into_ok();
|
||||
|
||||
|
||||
@@ -459,17 +459,11 @@ impl Bytes for Effect {
|
||||
}
|
||||
|
||||
/// A possible effect
|
||||
#[repr(transparent)]
|
||||
#[derive(ref_cast::RefCast)]
|
||||
#[derive(derive_more::From, derive_more::Into)]
|
||||
pub struct MaybeEffect(Option<Effect>);
|
||||
|
||||
impl<'a> From<&'a Option<Effect>> for &'a MaybeEffect {
|
||||
#[allow(clippy::as_conversions)] // We need `as` to make pointer casts
|
||||
fn from(opt: &'a Option<Effect>) -> Self {
|
||||
// SAFETY: We're `repr(transparent)`, so this cast is safe
|
||||
unsafe { &*(opt as *const Option<Effect> as *const MaybeEffect) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Bytes for MaybeEffect {
|
||||
type ByteArray = [u8; 0x10];
|
||||
type FromError = FromBytesError;
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::{
|
||||
};
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use dcb_bytes::Bytes;
|
||||
use ref_cast::RefCast;
|
||||
|
||||
/// A digimon's support effect condition
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
|
||||
@@ -119,7 +120,7 @@ impl Bytes for EffectCondition {
|
||||
self.property_cmp.to_bytes(bytes.property_cmp).into_ok();
|
||||
|
||||
// Arguments
|
||||
<&MaybeDigimonProperty>::from(&self.arg_property).to_bytes(bytes.arg_property).into_ok();
|
||||
MaybeDigimonProperty::ref_cast(&self.arg_property).to_bytes(bytes.arg_property).into_ok();
|
||||
LittleEndian::write_u16(bytes.arg_num, self.arg_num);
|
||||
self.operation.to_bytes(bytes.operation).into_ok();
|
||||
|
||||
@@ -137,18 +138,10 @@ impl Bytes for EffectCondition {
|
||||
|
||||
/// A possible effect condition
|
||||
#[repr(transparent)]
|
||||
#[derive(ref_cast::RefCast)]
|
||||
#[derive(derive_more::From, derive_more::Into)]
|
||||
pub struct MaybeEffectCondition(Option<EffectCondition>);
|
||||
|
||||
impl<'a> From<&'a Option<EffectCondition>> for &'a MaybeEffectCondition {
|
||||
#[allow(clippy::as_conversions)] // We need `as` to make pointer casts
|
||||
fn from(opt: &'a Option<EffectCondition>) -> Self {
|
||||
// SAFETY: We're `repr(transparent)`, so this cast is safe
|
||||
unsafe { &*(opt as *const Option<EffectCondition> as *const MaybeEffectCondition) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Bytes for MaybeEffectCondition {
|
||||
type ByteArray = [u8; 0x20];
|
||||
type FromError = FromBytesError;
|
||||
|
||||
@@ -11,6 +11,7 @@ use crate::{
|
||||
};
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use dcb_bytes::Bytes;
|
||||
use ref_cast::RefCast;
|
||||
|
||||
/// Card id type
|
||||
pub type CardId = u16;
|
||||
@@ -158,14 +159,14 @@ impl Bytes for Deck {
|
||||
*bytes.experience = self.experience;
|
||||
|
||||
// City
|
||||
<&MaybeCity>::from(&self.city).to_bytes(bytes.city).into_ok();
|
||||
MaybeCity::ref_cast(&self.city).to_bytes(bytes.city).into_ok();
|
||||
|
||||
// Armor evo
|
||||
<&MaybeArmorEvo>::from(&self.armor_evo).to_bytes(bytes.armor_evo).into_ok();
|
||||
MaybeArmorEvo::ref_cast(&self.armor_evo).to_bytes(bytes.armor_evo).into_ok();
|
||||
|
||||
// Music
|
||||
<&MaybeMusic>::from(&self.battle_music).to_bytes(bytes.battle_music).into_ok();
|
||||
<&MaybeMusic>::from(&self.polygon_music).to_bytes(bytes.polygon_music).into_ok();
|
||||
MaybeMusic::ref_cast(&self.battle_music).to_bytes(bytes.battle_music).into_ok();
|
||||
MaybeMusic::ref_cast(&self.polygon_music).to_bytes(bytes.polygon_music).into_ok();
|
||||
|
||||
// Unknown
|
||||
*bytes.unknown_64 = self.unknown_64;
|
||||
|
||||
@@ -142,17 +142,10 @@ pub macro generate_enum_property_option (
|
||||
) {
|
||||
$(
|
||||
#[repr(transparent)]
|
||||
#[derive(derive_more::From, derive_more::Into)]
|
||||
#[derive(::ref_cast::RefCast)]
|
||||
#[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) }
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::diverging_sub_expression)] // Errors might be `!`
|
||||
impl ::dcb_bytes::Bytes for $struct_name {
|
||||
type ByteArray = <$enum_name as ::dcb_bytes::Bytes>::ByteArray;
|
||||
|
||||
Reference in New Issue
Block a user