mod reader;
mod writer;
pub use self::reader::Reader;
pub use self::writer::Writer;
use crate::MAX_FILE_NAME_LEN;
#[derive(Debug)]
pub enum Error {
InvalidMagic { magic: [u8; 7] },
InvalidVersion { version: u8 },
FileNameTooLongU32 { len: u32 },
FileNameTooLongUsize { len: usize },
InvalidFileName {
error: std::string::FromUtf8Error,
},
FileDataSizeMismatch { actual: u32, expected: u32 },
InvalidState,
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::InvalidMagic { magic } => write!(f, "magic number \"{magic:?}\" is invalid"),
Self::InvalidVersion { version } => write!(f, "version \"{version}\" is invalid"),
Self::FileNameTooLongU32 { len } => write!(
f,
"file name {len} is too long, max length is {MAX_FILE_NAME_LEN}"
),
Self::FileNameTooLongUsize { len } => write!(
f,
"file name {len} is too long, max length is {MAX_FILE_NAME_LEN}"
),
Self::InvalidFileName { .. } => write!(f, "invalid file name"),
Self::FileDataSizeMismatch { actual, expected } => write!(
f,
"file data size mismatch, expected {expected} but got {actual}"
),
Self::InvalidState => {
write!(f, "programmer error, invalid internal state for function")
}
}
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::InvalidFileName { error } => Some(error),
_ => None,
}
}
}
#[derive(Debug, Copy, Clone)]
pub enum ReaderAction<T> {
Read(usize),
Seek(u64),
Done(T),
}
impl<T> ReaderAction<T> {
pub fn is_done(&self) -> bool {
matches!(self, Self::Done(_))
}
fn map_done<F, O>(self, f: F) -> ReaderAction<O>
where
F: FnOnce(T) -> O,
{
match self {
Self::Read(n) => ReaderAction::Read(n),
Self::Seek(p) => ReaderAction::Seek(p),
Self::Done(v) => ReaderAction::Done(f(v)),
}
}
}
#[derive(Debug, Copy, Clone)]
pub enum WriterAction<T> {
Write,
Done(T),
}
impl<T> WriterAction<T> {
pub fn is_done(&self) -> bool {
matches!(self, Self::Done(_))
}
fn map_done<F, O>(self, f: F) -> WriterAction<O>
where
F: FnOnce(T) -> O,
{
match self {
Self::Write => WriterAction::Write,
Self::Done(v) => WriterAction::Done(f(v)),
}
}
}
#[derive(Debug)]
pub struct FileHeader {
pub name: String,
pub size: u32,
}