better C enum handling and organization
parent
4c590a0dc2
commit
24c3ccc680
|
@ -0,0 +1,68 @@
|
|||
//! C representation enumerations.
|
||||
|
||||
/// Creates an enumeration and function for converting a representation into
|
||||
/// the enumeration type.
|
||||
#[macro_export]
|
||||
macro_rules! c_enum
|
||||
{
|
||||
(
|
||||
$(#[$outer:meta])*
|
||||
pub enum $E:ident: $T:ty
|
||||
{
|
||||
$($value:expr => $Enum:ident,)+
|
||||
}
|
||||
) => {
|
||||
$(#[$outer])*
|
||||
pub enum $E
|
||||
{
|
||||
$($Enum,)+
|
||||
}
|
||||
|
||||
impl $E
|
||||
{
|
||||
pub fn from_repr(n: $T) -> Result<$E, ReprError<$T>>
|
||||
{
|
||||
match n {
|
||||
$($value => Ok($E::$Enum),)+
|
||||
n => Err(ReprError(n))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test
|
||||
{
|
||||
use crate::durandal::err::ReprError;
|
||||
|
||||
c_enum! {
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum TestEnum: u16
|
||||
{
|
||||
0 => Zero,
|
||||
1 => One,
|
||||
2 => Two,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn c_enum_should_be_ok()
|
||||
{
|
||||
assert_eq!(TestEnum::from_repr(0), Ok(TestEnum::Zero));
|
||||
assert_eq!(TestEnum::from_repr(1), Ok(TestEnum::One));
|
||||
assert_eq!(TestEnum::from_repr(2), Ok(TestEnum::Two));
|
||||
assert_eq!(TestEnum::from_repr(3), Err(ReprError(3)));
|
||||
assert_eq!(TestEnum::from_repr(4), Err(ReprError(4)));
|
||||
assert_eq!(TestEnum::from_repr(5), Err(ReprError(5)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn c_enum_should_error()
|
||||
{
|
||||
TestEnum::from_repr(3).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
// EOF
|
|
@ -2,6 +2,26 @@
|
|||
|
||||
pub use failure::{Error, Fail, format_err};
|
||||
|
||||
use crate::durandal::traits::PrimInt;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub struct ReprError<T>(pub T) where T: PrimInt;
|
||||
|
||||
impl<T> Fail for ReprError<T> where T: PrimInt {}
|
||||
|
||||
impl<T> fmt::Display for ReprError<T> where T: PrimInt
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
|
||||
{write!(f, "representation error (got {})", self.0)}
|
||||
}
|
||||
|
||||
impl<T> fmt::Debug for ReprError<T> where T: PrimInt
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
|
||||
{fmt::Display::fmt(self, f)}
|
||||
}
|
||||
|
||||
pub type ResultS<T> = Result<T, Error>;
|
||||
|
||||
pub fn err_msg<T>(s: &'static str) -> ResultS<T> {Err(failure::err_msg(s))}
|
||||
|
|
|
@ -2,44 +2,14 @@
|
|||
|
||||
#[allow(dead_code)]
|
||||
pub mod bin;
|
||||
#[macro_use]
|
||||
pub mod cenum;
|
||||
pub mod chunk;
|
||||
pub mod crc;
|
||||
pub mod err;
|
||||
pub mod fx32;
|
||||
pub mod image;
|
||||
pub mod machead;
|
||||
pub mod text;
|
||||
|
||||
/// Creates an enumeration and function for converting a representation into
|
||||
/// the enumeration type.
|
||||
#[macro_export]
|
||||
macro_rules! c_enum
|
||||
{
|
||||
(
|
||||
$(#[$outer:meta])*
|
||||
pub enum $E:ident: $T:ty
|
||||
{
|
||||
$($value:expr => $Enum:ident,)+
|
||||
}
|
||||
) => {
|
||||
$(#[$outer])*
|
||||
pub enum $E
|
||||
{
|
||||
$($Enum,)+
|
||||
}
|
||||
|
||||
impl $E
|
||||
{
|
||||
pub fn from_repr(n: $T) -> ResultS<$E>
|
||||
{
|
||||
let t = match n {
|
||||
$($value => $E::$Enum,)+
|
||||
n => return Err(format_err!("invalid representation for {} (got {})", stringify!($E), n))
|
||||
};
|
||||
Ok(t)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
pub mod traits;
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
//! Traits for basic types, because Rust doesn't provide them.
|
||||
|
||||
/// Any primitive integer type.
|
||||
pub trait PrimInt: 'static + Send + Sync + std::fmt::Display + PartialEq {}
|
||||
|
||||
impl PrimInt for u8 {}
|
||||
impl PrimInt for i8 {}
|
||||
impl PrimInt for u16 {}
|
||||
impl PrimInt for i16 {}
|
||||
impl PrimInt for u32 {}
|
||||
impl PrimInt for i32 {}
|
||||
impl PrimInt for u64 {}
|
||||
impl PrimInt for i64 {}
|
||||
impl PrimInt for u128 {}
|
||||
impl PrimInt for i128 {}
|
||||
|
||||
// EOF
|
|
@ -1,5 +1,5 @@
|
|||
use maraiah::durandal::{chunk::*, err::*, image::Image};
|
||||
use maraiah::marathon::{map, pict, term, wad};
|
||||
use maraiah::marathon::{machdr, map, pict, term, wad};
|
||||
use memmap::Mmap;
|
||||
use std::{io, io::Write, fs, env};
|
||||
|
||||
|
@ -25,7 +25,7 @@ fn main() -> ResultS<()>
|
|||
let arg = env::args().nth(1).expect("need at least 1 argument");
|
||||
let fp = fs::File::open(arg)?;
|
||||
let mm = unsafe{Mmap::map(&fp)?};
|
||||
let wad = wad::Wad::new(&mm)?;
|
||||
let wad = wad::Wad::new(&mm[machdr::try_mac_header(&mm)..])?;
|
||||
|
||||
println!("{:#?}", wad);
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
//! Library for file data formats.
|
||||
|
||||
pub mod machdr;
|
||||
pub mod map;
|
||||
pub mod pict;
|
||||
pub mod term;
|
||||
|
|
|
@ -148,7 +148,7 @@ pub fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Re
|
|||
/// Process a CompressedQuickTime operation.
|
||||
pub fn read_quicktime_c(_im: Image, _b: &[u8]) -> ResultS<Image>
|
||||
{
|
||||
err_msg("compressed quicktime format not implemented")
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// Load a PICT image.
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
//! Marathon Wad format handling.
|
||||
|
||||
use crate::durandal::{bin::*, err::*, machead::try_mac_header, text::mac_roman_conv};
|
||||
use crate::durandal::{bin::*, err::*, text::mac_roman_conv};
|
||||
use std::{collections::BTreeMap, fmt};
|
||||
|
||||
impl Wad<'_>
|
||||
{
|
||||
pub fn new(b: &[u8]) -> ResultS<Wad>
|
||||
{
|
||||
let b = &b[try_mac_header(b)..];
|
||||
if b.len() < 128 {return err_msg("not enough data for Wad header");}
|
||||
|
||||
let wadver = b.c_u16b( 0)?;
|
||||
|
@ -89,7 +88,7 @@ pub struct Wad<'a>
|
|||
}
|
||||
|
||||
c_enum! {
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug)]
|
||||
pub enum Ver: u16
|
||||
{
|
||||
0 => Base,
|
||||
|
|
Loading…
Reference in New Issue