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};
|
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 type ResultS<T> = Result<T, Error>;
|
||||||
|
|
||||||
pub fn err_msg<T>(s: &'static str) -> ResultS<T> {Err(failure::err_msg(s))}
|
pub fn err_msg<T>(s: &'static str) -> ResultS<T> {Err(failure::err_msg(s))}
|
||||||
|
|
|
@ -2,44 +2,14 @@
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub mod bin;
|
pub mod bin;
|
||||||
|
#[macro_use]
|
||||||
|
pub mod cenum;
|
||||||
pub mod chunk;
|
pub mod chunk;
|
||||||
pub mod crc;
|
pub mod crc;
|
||||||
pub mod err;
|
pub mod err;
|
||||||
pub mod fx32;
|
pub mod fx32;
|
||||||
pub mod image;
|
pub mod image;
|
||||||
pub mod machead;
|
|
||||||
pub mod text;
|
pub mod text;
|
||||||
|
pub mod traits;
|
||||||
/// 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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// EOF
|
// 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::durandal::{chunk::*, err::*, image::Image};
|
||||||
use maraiah::marathon::{map, pict, term, wad};
|
use maraiah::marathon::{machdr, map, pict, term, wad};
|
||||||
use memmap::Mmap;
|
use memmap::Mmap;
|
||||||
use std::{io, io::Write, fs, env};
|
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 arg = env::args().nth(1).expect("need at least 1 argument");
|
||||||
let fp = fs::File::open(arg)?;
|
let fp = fs::File::open(arg)?;
|
||||||
let mm = unsafe{Mmap::map(&fp)?};
|
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);
|
println!("{:#?}", wad);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
//! Library for file data formats.
|
//! Library for file data formats.
|
||||||
|
|
||||||
|
pub mod machdr;
|
||||||
pub mod map;
|
pub mod map;
|
||||||
pub mod pict;
|
pub mod pict;
|
||||||
pub mod term;
|
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.
|
/// Process a CompressedQuickTime operation.
|
||||||
pub fn read_quicktime_c(_im: Image, _b: &[u8]) -> ResultS<Image>
|
pub fn read_quicktime_c(_im: Image, _b: &[u8]) -> ResultS<Image>
|
||||||
{
|
{
|
||||||
err_msg("compressed quicktime format not implemented")
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load a PICT image.
|
/// Load a PICT image.
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
//! Marathon Wad format handling.
|
//! 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};
|
use std::{collections::BTreeMap, fmt};
|
||||||
|
|
||||||
impl Wad<'_>
|
impl Wad<'_>
|
||||||
{
|
{
|
||||||
pub fn new(b: &[u8]) -> ResultS<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");}
|
if b.len() < 128 {return err_msg("not enough data for Wad header");}
|
||||||
|
|
||||||
let wadver = b.c_u16b( 0)?;
|
let wadver = b.c_u16b( 0)?;
|
||||||
|
@ -89,7 +88,7 @@ pub struct Wad<'a>
|
||||||
}
|
}
|
||||||
|
|
||||||
c_enum! {
|
c_enum! {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Ver: u16
|
pub enum Ver: u16
|
||||||
{
|
{
|
||||||
0 => Base,
|
0 => Base,
|
||||||
|
|
Loading…
Reference in New Issue