mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'src/content.rs')
| -rw-r--r-- | src/content.rs | 211 |
1 files changed, 91 insertions, 120 deletions
diff --git a/src/content.rs b/src/content.rs index 5f04dc8..3172096 100644 --- a/src/content.rs +++ b/src/content.rs @@ -1,177 +1,148 @@ use std::error::Error; -macro_rules!numeric_enum -{ +macro_rules! numeric_enum { ($vis:vis enum $tname:ident for $numeric:ty | $error:ident {$($name:ident $(= $val:literal)?),* $(,)?}) => { crate::content::numeric_enum!($vis enum $tname for $numeric | $error* {$($name $(= $val)?),*}); - - impl std::fmt::Display for $error - { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result - { + + impl std::fmt::Display for $error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "no variant of {} for value {}", stringify!($tname), self.0) } } - + impl std::error::Error for $error {} }; ($vis:vis enum $tname:ident for $numeric:ty | $error:ident* {$($name:ident $(= $val:literal)?),* $(,)?}) => { #[repr($numeric)] #[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] - $vis enum $tname - { - $($name $(= $val)?,)+ - } - + $vis enum $tname { $($name $(= $val)?,)+ } + #[derive(Copy, Clone, Debug, Eq, PartialEq)] $vis struct $error($vis $numeric); - - impl TryFrom<$numeric> for $tname - { + + impl TryFrom<$numeric> for $tname { type Error = $error; - + #[allow(non_upper_case_globals)] - fn try_from(value: $numeric) -> Result<Self, $error> - { + fn try_from(value: $numeric) -> Result<Self, $error> { $(const $name: $numeric = $tname::$name as $numeric;)+ - match value - { + match value { $($name => Ok(Self::$name),)+ _ => Err($error(value)), } } } - - impl From<$tname> for $numeric - { - fn from(value: $tname) -> $numeric - { - value as $numeric - } - } + + impl From<$tname> for $numeric { fn from(value: $tname) -> $numeric { value as $numeric } } }; } + pub(crate) use numeric_enum; -macro_rules!content_enum -{ - ($vis:vis enum $tname:ident / $ctype:ident for u16 | $error:ident {$($name:ident $(= $val:literal)? => $vname:expr),* $(,)?}) => +macro_rules! content_enum { + ($vis:vis enum $tname:ident / $ctype:ident for u16 | $error:ident {$($val:literal),* $(,)?}) => { - $crate::content::numeric_enum!($vis enum $tname for u16 | $error* {$($name $(= $val)?),*}); - - impl $crate::content::Content for $tname - { - fn get_type(&self) -> $crate::content::Type - { + paste::paste! { + $crate::content::numeric_enum!($vis enum $tname for u16 | $error* { + $([<$val:camel>]),*, + }); + + impl $crate::content::Content for $tname { + fn get_type(&self) -> $crate::content::Type { $crate::content::Type::$ctype } - - fn get_id(&self) -> u16 - { + + fn get_id(&self) -> u16 { *self as u16 } - - fn get_name(&self) -> &'static str - { - match self - { - $(Self::$name => $vname,)* + + fn get_name(&self) -> &'static str { + match self { + $(Self::[<$val:camel>] => $val,)* } } } - + impl std::fmt::Display for $error { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result - { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "no content of type {} for value {}", stringify!($ctype), self.0) } } - + impl std::error::Error for $error {} + } }; } pub(crate) use content_enum; -numeric_enum! -{ - pub enum Type for u8 | TryFromU8Error - { - Item = 0, - Block = 1, - // Mech = 2, - Bullet = 3, - Fluid = 4, - Modifier = 5, - Unit = 6, - Weather = 7, - // Effect = 8, - Sector = 9, - // Loadout = 10, - // TypeId = 11, - // Error = 12, - Planet = 13, - // Ammo = 14, - Team = 15, - } +numeric_enum! { + pub enum Type for u8 | TryFromU8Error + { + Item = 0, + Block = 1, + // Mech = 2, + Bullet = 3, + Fluid = 4, + Modifier = 5, + Unit = 6, + Weather = 7, + // Effect = 8, + Sector = 9, + // Loadout = 10, + // TypeId = 11, + // Error = 12, + Planet = 13, + // Ammo = 14, + Team = 15, + } } -macro_rules!gen_by_id -{ - ($target:path, $id:expr) => - { - match <$target>::try_from($id) - { - Ok(v) => Ok(Box::new(v)), - Err(e) => Err(Box::new(e)), - } - }; +macro_rules! gen_by_id { + ($target:path, $id:expr) => { + match <$target>::try_from($id) { + Ok(v) => Ok(Box::new(v)), + Err(e) => Err(Box::new(e)), + } + }; } -impl Type -{ - pub fn get(&self, id: u16) -> Result<Box<dyn Content>, Box<dyn Error>> - { - match self - { - Self::Item => gen_by_id!(crate::item::Type, id), - Self::Block => gen_by_id!(crate::block::content::Type, id), - Self::Fluid => gen_by_id!(crate::fluid::Type, id), - Self::Modifier => gen_by_id!(crate::modifier::Type, id), - Self::Unit => gen_by_id!(crate::unit::Type, id), - Self::Team => gen_by_id!(crate::team::Team, id), - _ => Ok(Box::new(Generic(*self, id))), - } - } +impl Type { + pub fn get(&self, id: u16) -> Result<Box<dyn Content>, Box<dyn Error>> { + match self { + Self::Item => gen_by_id!(crate::item::Type, id), + Self::Block => gen_by_id!(crate::block::content::Type, id), + Self::Fluid => gen_by_id!(crate::fluid::Type, id), + Self::Modifier => gen_by_id!(crate::modifier::Type, id), + Self::Unit => gen_by_id!(crate::unit::Type, id), + Self::Team => gen_by_id!(crate::team::Team, id), + _ => Ok(Box::new(Generic(*self, id))), + } + } } -pub trait Content -{ - fn get_type(&self) -> Type; - - fn get_id(&self) -> u16; - - fn get_name(&self) -> &str; +pub trait Content { + fn get_type(&self) -> Type; + + fn get_id(&self) -> u16; + + fn get_name(&self) -> &str; } struct Generic(Type, u16); -impl Content for Generic -{ - fn get_type(&self) -> Type - { - self.0 - } - - fn get_id(&self) -> u16 - { - self.1 - } - - fn get_name(&self) -> &str - { - "<unknown>" - } +impl Content for Generic { + fn get_type(&self) -> Type { + self.0 + } + + fn get_id(&self) -> u16 { + self.1 + } + + fn get_name(&self) -> &str { + "<unknown>" + } } |