simplify c_enum API

gui-branch
an 2019-03-18 12:22:10 -04:00
parent ee35332b23
commit b830718258
8 changed files with 151 additions and 151 deletions

View File

@ -6,7 +6,7 @@
/// The syntax is similar to the `bitflags` macro, but each value has the /// The syntax is similar to the `bitflags` macro, but each value has the
/// syntax `value => enumeration`. `enum` is used instead of `struct`. /// syntax `value => enumeration`. `enum` is used instead of `struct`.
/// ///
/// This will generate an `enum $t` as well as a function `$t::from_repr` which /// This will generate an `enum $t` as well as a function `$t::try_from` which
/// will return `Result<$t, ReprError>`. /// will return `Result<$t, ReprError>`.
/// ///
/// # Examples /// # Examples
@ -18,18 +18,18 @@
/// #[derive(Debug)] /// #[derive(Debug)]
/// enum MyEnum: u16 /// enum MyEnum: u16
/// { /// {
/// 0 => Zero, /// Zero = 0,
/// 1 => One, /// One = 1,
/// 2 => Two, /// Two = 2
/// } /// }
/// } /// }
/// ///
/// assert_eq!(MyEnum::from_repr(0), Ok(MyEnum::Zero)); /// assert_eq!(MyEnum::try_from(0), Ok(MyEnum::Zero));
/// assert_eq!(MyEnum::from_repr(1), Ok(MyEnum::One)); /// assert_eq!(MyEnum::try_from(1), Ok(MyEnum::One));
/// assert_eq!(MyEnum::from_repr(2), Ok(MyEnum::Two)); /// assert_eq!(MyEnum::try_from(2), Ok(MyEnum::Two));
/// assert_eq!(MyEnum::from_repr(3), Err(ReprError::new(3))); /// assert_eq!(MyEnum::try_from(3), Err(ReprError::new(3)));
/// assert_eq!(MyEnum::from_repr(4), Err(ReprError::new(4))); /// assert_eq!(MyEnum::try_from(4), Err(ReprError::new(4)));
/// assert_eq!(MyEnum::from_repr(5), Err(ReprError::new(5))); /// assert_eq!(MyEnum::try_from(5), Err(ReprError::new(5)));
/// ``` /// ```
#[macro_export] #[macro_export]
macro_rules! c_enum macro_rules! c_enum
@ -38,12 +38,12 @@ macro_rules! c_enum
$(#[$outer:meta])* $(#[$outer:meta])*
$vi:vis enum $t:ident: $ti:ident $vi:vis enum $t:ident: $ti:ident
{ {
$($va:expr => $en:ident,)+ $($en:ident = $va:expr),+ $(,)?
} }
) => { ) => {
$(#[$outer])* $(#[$outer])*
#[repr($ti)]
#[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd)] #[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd)]
#[repr($ti)]
$vi enum $t $vi enum $t
{ {
$($en = $va,)+ $($en = $va,)+
@ -52,7 +52,7 @@ macro_rules! c_enum
impl $t impl $t
{ {
/// Returns, if representable, the variant of `Self` from `n`. /// Returns, if representable, the variant of `Self` from `n`.
$vi fn from_repr(n: $ti) -> Result<Self, ReprError> $vi fn try_from(n: $ti) -> Result<Self, ReprError>
{ {
match n { match n {
$($va => Ok($t::$en),)+ $($va => Ok($t::$en),)+
@ -72,26 +72,26 @@ mod test
#[derive(Debug)] #[derive(Debug)]
enum TestEnum: u16 enum TestEnum: u16
{ {
0 => Zero, Zero = 0,
1 => One, One = 1,
2 => Two, Two = 2,
} }
} }
#[test] #[test]
fn c_enum_should_be_ok() fn c_enum_should_be_ok()
{ {
assert_eq!(TestEnum::from_repr(0), Ok(TestEnum::Zero)); assert_eq!(TestEnum::try_from(0), Ok(TestEnum::Zero));
assert_eq!(TestEnum::from_repr(1), Ok(TestEnum::One)); assert_eq!(TestEnum::try_from(1), Ok(TestEnum::One));
assert_eq!(TestEnum::from_repr(2), Ok(TestEnum::Two)); assert_eq!(TestEnum::try_from(2), Ok(TestEnum::Two));
assert_eq!(TestEnum::from_repr(3), Err(ReprError::new(3))); assert_eq!(TestEnum::try_from(3), Err(ReprError::new(3)));
assert_eq!(TestEnum::from_repr(4), Err(ReprError::new(4))); assert_eq!(TestEnum::try_from(4), Err(ReprError::new(4)));
assert_eq!(TestEnum::from_repr(5), Err(ReprError::new(5))); assert_eq!(TestEnum::try_from(5), Err(ReprError::new(5)));
} }
#[test] #[test]
#[should_panic] #[should_panic]
fn c_enum_should_error() {TestEnum::from_repr(3).unwrap();} fn c_enum_should_error() {TestEnum::try_from(3).unwrap();}
} }
// EOF // EOF

View File

@ -16,7 +16,7 @@ pub fn read_lightfunc(b: &[u8]) -> ResultS<LightFunc>
val_dta = Fixed[10]; val_dta = Fixed[10];
} }
let ftype = LightFuncType::from_repr(ftype)?; let ftype = LightFuncType::try_from(ftype)?;
Ok(LightFunc{ftype, prd_nrm, prd_dta, val_nrm, val_dta}) Ok(LightFunc{ftype, prd_nrm, prd_dta, val_nrm, val_dta})
} }
@ -148,10 +148,10 @@ pub fn read_sids(b: &[u8]) -> ResultS<(Side, usize)>
} }
let flags = flag_ok!(SideFlags, flags)?; let flags = flag_ok!(SideFlags, flags)?;
let xfer_pri = TransferMode::from_repr(xfer_pri)?; let xfer_pri = TransferMode::try_from(xfer_pri)?;
let xfer_sec = TransferMode::from_repr(xfer_sec)?; let xfer_sec = TransferMode::try_from(xfer_sec)?;
let xfer_tra = TransferMode::from_repr(xfer_tra)?; let xfer_tra = TransferMode::try_from(xfer_tra)?;
let stype = SideType::from_repr(stype)?; let stype = SideType::try_from(stype)?;
Ok((Side{stype, flags, tex_pri, tex_sec, tex_tra, paneltyp, paneldat, Ok((Side{stype, flags, tex_pri, tex_sec, tex_tra, paneltyp, paneldat,
xfer_pri, xfer_sec, xfer_tra, shade}, 64)) xfer_pri, xfer_sec, xfer_tra, shade}, 64))
@ -183,8 +183,8 @@ fn read_poly_inter(b: &[u8]) -> ResultS<Polygon>
xfr_cei = u16[66]; xfr_cei = u16[66];
} }
let xfr_flr = TransferMode::from_repr(xfr_flr)?; let xfr_flr = TransferMode::try_from(xfr_flr)?;
let xfr_cei = TransferMode::from_repr(xfr_cei)?; let xfr_cei = TransferMode::try_from(xfr_cei)?;
Ok(Polygon{tex_flr, tex_cei, hei_flr, hei_cei, lit_flr, lit_cei, xfr_flr, Ok(Polygon{tex_flr, tex_cei, hei_flr, hei_cei, lit_flr, lit_cei, xfr_flr,
xfr_cei, ..Default::default()}) xfr_cei, ..Default::default()})
@ -246,7 +246,7 @@ pub fn read_lite(b: &[u8]) -> ResultS<(Light, usize)>
} }
let flags = flag_ok!(LightFlags, flags)?; let flags = flag_ok!(LightFlags, flags)?;
let ltype = LightType::from_repr(ltype)?; let ltype = LightType::try_from(ltype)?;
Ok((Light{ltype, flags, phase, act_pri, act_sec, act_mid, ina_pri, ina_sec, Ok((Light{ltype, flags, phase, act_pri, act_sec, act_mid, ina_pri, ina_sec,
ina_mid, tag}, 100)) ina_mid, tag}, 100))
@ -390,8 +390,8 @@ pub fn read_medi(b: &[u8]) -> ResultS<(Media, usize)>
xfer = u16[26]; xfer = u16[26];
} }
let mtype = MediaType::from_repr(mtype)?; let mtype = MediaType::try_from(mtype)?;
let xfer = TransferMode::from_repr(xfer)?; let xfer = TransferMode::try_from(xfer)?;
let flr_obs = flags != 0; let flr_obs = flags != 0;
Ok((Media{mtype, flr_obs, control, dir, mag, hei_lo, hei_hi, orig, hei_nrm, Ok((Media{mtype, flr_obs, control, dir, mag, hei_lo, hei_hi, orig, hei_nrm,
@ -908,11 +908,11 @@ c_enum! {
#[derive(Debug)] #[derive(Debug)]
pub enum SideType: u16 pub enum SideType: u16
{ {
0 => Full, Full = 0,
1 => High, High = 1,
2 => Low, Low = 2,
3 => Composite, Composite = 3,
4 => Split, Split = 4,
} }
} }
@ -922,12 +922,12 @@ c_enum! {
#[derive(Debug)] #[derive(Debug)]
pub enum LightFuncType: u16 pub enum LightFuncType: u16
{ {
0 => Constant, Constant = 0,
1 => Linear, Linear = 1,
2 => Smooth, Smooth = 2,
3 => Flicker, Flicker = 3,
4 => Random, Random = 4,
5 => Fluorescent, Fluorescent = 5,
} }
} }
@ -937,9 +937,9 @@ c_enum! {
#[derive(Debug)] #[derive(Debug)]
pub enum LightType: u16 pub enum LightType: u16
{ {
0 => Normal, Normal = 0,
1 => Strobe, Strobe = 1,
2 => Media, Media = 2,
} }
} }
@ -949,10 +949,10 @@ c_enum! {
#[derive(Debug)] #[derive(Debug)]
pub enum MediaType: u16 pub enum MediaType: u16
{ {
0 => Water, Water = 0,
1 => Lava, Lava = 1,
2 => Goo, Goo = 2,
3 => Sewage, Sewage = 3,
} }
} }

View File

@ -92,7 +92,7 @@ pub fn read_wppx(b: &[u8]) -> ResultS<(Weapon, usize)>
trig_sec = read_trigger[98..134]; trig_sec = read_trigger[98..134];
} }
let typ_weapon = WeaponType::from_repr(typ_weapon)?; let typ_weapon = WeaponType::try_from(typ_weapon)?;
let flags = flag_ok!(WeaponFlags, flags)?; let flags = flag_ok!(WeaponFlags, flags)?;
Ok((Weapon{amp_bob, amp_horz, collection, flags, frm_charge, frm_charged, Ok((Weapon{amp_bob, amp_horz, collection, flags, frm_charge, frm_charged,
@ -239,7 +239,7 @@ fn read_trigger(b: &[u8]) -> ResultS<Trigger>
burst = u16[34]; burst = u16[34];
} }
let typ_casing = CasingType::from_repr(typ_casing)?; let typ_casing = CasingType::try_from(typ_casing)?;
Ok(Trigger{burst, dx, dz, magazine, recoil, snd_casing, snd_charge, Ok(Trigger{burst, dx, dz, magazine, recoil, snd_casing, snd_charge,
snd_charged, snd_click, snd_fire, snd_reload, theta, tic_charge, snd_charged, snd_click, snd_fire, snd_reload, theta, tic_charge,
@ -258,7 +258,7 @@ fn read_damage(b: &[u8]) -> ResultS<Damage>
scale = Fixed[8]; scale = Fixed[8];
} }
let dtype = DamageType::from_repr(dtype)?; let dtype = DamageType::try_from(dtype)?;
let alien = flags != 0; let alien = flags != 0;
Ok(Damage{dtype, alien, dmg_base, dmg_rand, scale}) Ok(Damage{dtype, alien, dmg_base, dmg_rand, scale})
@ -653,12 +653,12 @@ c_enum! {
#[derive(Debug)] #[derive(Debug)]
pub enum CasingType: u16 pub enum CasingType: u16
{ {
0 => Rifle, Rifle = 0,
1 => Pistol, Pistol = 1,
2 => PistolLeft, PistolLeft = 2,
3 => PistolRight, PistolRight = 3,
4 => SMG, SMG = 4,
0xFFFF => None, None = 0xFFFF,
} }
} }
@ -668,11 +668,11 @@ c_enum! {
#[derive(Debug)] #[derive(Debug)]
pub enum WeaponType: u16 pub enum WeaponType: u16
{ {
0 => Melee, Melee = 0,
1 => Normal, Normal = 1,
2 => DualFunc, DualFunc = 2,
3 => DualPistol, DualPistol = 3,
4 => Multipurpose, Multipurpose = 4,
} }
} }
@ -682,31 +682,31 @@ c_enum! {
#[derive(Debug)] #[derive(Debug)]
pub enum DamageType: u16 pub enum DamageType: u16
{ {
0 => Explosion, Explosion = 0,
1 => ElectricalStaff, ElectricalStaff = 1,
2 => Projectile, Projectile = 2,
3 => Absorbed, Absorbed = 3,
4 => Flame, Flame = 4,
5 => HoundClaws, HoundClaws = 5,
6 => AlienProjectile, AlienProjectile = 6,
7 => HulkSlap, HulkSlap = 7,
8 => CompilerBolt, CompilerBolt = 8,
9 => FusionBolt, FusionBolt = 9,
10 => HunterBolt, HunterBolt = 10,
11 => Fist, Fist = 11,
12 => Teleporter, Teleporter = 12,
13 => Defender, Defender = 13,
14 => YetiClaws, YetiClaws = 14,
15 => YetiProjectile, YetiProjectile = 15,
16 => Crushing, Crushing = 16,
17 => Lava, Lava = 17,
18 => Suffocation, Suffocation = 18,
19 => Goo, Goo = 19,
20 => EnergyDrain, EnergyDrain = 20,
21 => OxygenDrain, OxygenDrain = 21,
22 => HummerBolt, HummerBolt = 22,
23 => ShotgunProjectile, ShotgunProjectile = 23,
0xFFFF => None, None = 0xFFFF,
} }
} }

View File

@ -20,8 +20,8 @@ fn read_pm_header<'a>(b: &'a [u8],
depth = u16[28]; depth = u16[28];
} }
let pack_t = PackType::from_repr(pack_t)?; let pack_t = PackType::try_from(pack_t)?;
let depth = Depth::from_repr(depth)?; let depth = Depth::try_from(depth)?;
if pt_fl & 0x8000 == 0 { if pt_fl & 0x8000 == 0 {
bail!("PICT1 not supported"); bail!("PICT1 not supported");
@ -481,23 +481,23 @@ struct Header
c_enum! { c_enum! {
enum Depth: u16 enum Depth: u16
{ {
1 => Bits1, Bits1 = 1,
2 => Bits2, Bits2 = 2,
4 => Bits4, Bits4 = 4,
8 => Bits8, Bits8 = 8,
16 => Bits16, Bits16 = 16,
32 => Bits32, Bits32 = 32,
} }
} }
c_enum! { c_enum! {
enum PackType: u16 enum PackType: u16
{ {
0 => Default, Default = 0,
1 => None, None = 1,
2 => NoPad, NoPad = 2,
3 => Rle16, Rle16 = 3,
4 => Rle32, Rle32 = 4,
} }
} }

View File

@ -158,8 +158,8 @@ pub fn read_sequence(b: &[u8]) -> ResultS<Sequence>
} }
let name = mac_roman_conv(ok!(pascal_str(name), "bad string")?); let name = mac_roman_conv(ok!(pascal_str(name), "bad string")?);
let xfer = TransferMode::from_repr(xfer)?; let xfer = TransferMode::try_from(xfer)?;
let v_type = ViewType::from_repr(v_type)?; let v_type = ViewType::try_from(v_type)?;
Ok(Sequence{name, v_type, frames, ticks, key, xfer, xfer_pd, snd_beg, Ok(Sequence{name, v_type, frames, ticks, key, xfer, xfer_pd, snd_beg,
snd_key, snd_end, loop_f}) snd_key, snd_end, loop_f})
@ -183,7 +183,7 @@ pub fn read_collection(b: &[u8]) -> ResultS<Collection>
bmp_ofs = u32[28] usize; bmp_ofs = u32[28] usize;
} }
let cl_type = CollectionType::from_repr(cl_type)?; let cl_type = CollectionType::try_from(cl_type)?;
if version != 3 { if version != 3 {
bail!("invalid collection definition"); bail!("invalid collection definition");
@ -478,11 +478,11 @@ c_enum! {
#[derive(Debug)] #[derive(Debug)]
pub enum CollectionType: u16 pub enum CollectionType: u16
{ {
0 => Unused, Unused = 0,
1 => Wall, Wall = 1,
2 => Object, Object = 2,
3 => Interface, Interface = 3,
4 => Scenery, Scenery = 4,
} }
} }
@ -492,15 +492,15 @@ c_enum! {
#[derive(Debug)] #[derive(Debug)]
pub enum ViewType: u16 pub enum ViewType: u16
{ {
1 => Anim, Anim = 1,
2 => Anim8from2, Anim8from2 = 2,
3 => Anim4from3, Anim4from3 = 3,
4 => Anim4, Anim4 = 4,
5 => Anim8from5, Anim8from5 = 5,
8 => Anim8, Anim8 = 8,
9 => Anim5from3, Anim5from3 = 9,
10 => Still, Still = 10,
11 => Anim5, Anim5 = 11,
} }
} }

View File

@ -60,7 +60,7 @@ pub fn read_sound_def(b: &[u8]) -> ResultS<Option<(Vec<usize>, u16, SoundDef)>>
} }
let flags = flag_ok!(SoundFlags, flags)?; let flags = flag_ok!(SoundFlags, flags)?;
let volume = Volume::from_repr(volume)?; let volume = Volume::try_from(volume)?;
if index == u16::max_value() { if index == u16::max_value() {
return Ok(None); return Ok(None);
@ -177,9 +177,9 @@ c_enum! {
#[derive(Debug)] #[derive(Debug)]
pub enum Volume: u16 pub enum Volume: u16
{ {
0 => Quiet, Quiet = 0,
1 => Normal, Normal = 1,
2 => Loud, Loud = 2,
} }
} }

View File

@ -112,7 +112,7 @@ pub fn read_wad(b: &[u8]) -> ResultS<Wad>
} }
let old_dat = ver_dat == 0; let old_dat = ver_dat == 0;
let old_wad = match Ver::from_repr(ver_wad)? { let old_wad = match Ver::try_from(ver_wad)? {
Ver::Base => true, Ver::Base => true,
_ => false, _ => false,
}; };
@ -217,10 +217,10 @@ c_enum! {
#[derive(Debug)] #[derive(Debug)]
enum Ver: u16 enum Ver: u16
{ {
0 => Base, Base = 0,
1 => Dir, Dir = 1,
2 => Over, Over = 2,
4 => Inf, Inf = 4,
} }
} }

View File

@ -13,28 +13,28 @@ c_enum! {
#[derive(Debug)] #[derive(Debug)]
pub enum TransferMode: u16 pub enum TransferMode: u16
{ {
0 => Normal, Normal = 0,
1 => FadeBlack, FadeBlack = 1,
2 => Invisibility, Invisibility = 2,
3 => Invisibility2, Invisibility2 = 3,
4 => Pulsate, Pulsate = 4,
5 => Wobble, Wobble = 5,
6 => Wobble2, Wobble2 = 6,
7 => Static, Static = 7,
8 => Static2, Static2 = 8,
9 => Sky, Sky = 9,
10 => Smear, Smear = 10,
11 => StaticFade, StaticFade = 11,
12 => StaticPulse, StaticPulse = 12,
13 => FoldIn, FoldIn = 13,
14 => FoldOut, FoldOut = 14,
15 => SlideHorz, SlideHorz = 15,
16 => SlideHorz2, SlideHorz2 = 16,
17 => SlideVert, SlideVert = 17,
18 => SlideVert2, SlideVert2 = 18,
19 => Wander, Wander = 19,
20 => Wander2, Wander2 = 20,
21 => BigSky, BigSky = 21,
} }
} }