use std::fmt;
use std::io::{self};
pub const HEADER: &[u8; 4] = b"GMAD";
pub const VERSION: i8 = 3;
mod reader;
pub use reader::read;
mod builder;
pub use builder::Builder;
#[derive(Clone, Debug, PartialEq, Eq, Default)]
pub struct GMAFile {
pub name: String,
pub content: Vec<u8>,
pub size: i64,
}
#[derive(Debug)]
pub enum GmaError {
Io(io::Error),
InvalidHeader([u8; 4]),
InvalidVersion(i8),
MissingNullTerminator, SizeOutOfRange(i64),
TrailingMarkerMismatch(u32),
}
impl fmt::Display for GmaError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
GmaError::Io(e) => write!(f, "io error: {e}"),
GmaError::InvalidHeader(got) => {
write!(f, "invalid header: {:?}", String::from_utf8_lossy(got))
}
GmaError::InvalidVersion(v) => write!(f, "invalid version: {v}"),
GmaError::MissingNullTerminator => write!(f, "missing null terminator in C string"),
GmaError::SizeOutOfRange(sz) => write!(f, "negative or invalid size: {sz}"),
GmaError::TrailingMarkerMismatch(v) => {
write!(f, "expected trailing 0 u32 marker, got {v}")
}
}
}
}
impl std::error::Error for GmaError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
if let GmaError::Io(e) = self {
Some(e)
} else {
None
}
}
}
impl From<io::Error> for GmaError {
fn from(e: io::Error) -> Self {
GmaError::Io(e)
}
}