use core::convert::Infallible;
use core::error::Error;
use core::fmt::{self, Display, Formatter};
use oct::IntoOcts;
#[cfg(feature = "std")]
use std::io;
#[derive(Debug)]
pub struct DecodeError(Inner);
impl DecodeError {
#[inline]
#[must_use]
pub(in crate::wad) fn end_of_file(found: usize, expected: usize) -> Self {
let inner = Inner::EndOfFile { found, expected };
Self(inner)
}
#[inline]
#[must_use]
pub(in crate::wad) fn large_size(temporary: u64) -> Self {
let inner = Inner::LargeSize { temporary };
Self(inner)
}
#[inline]
#[must_use]
pub(in crate::wad) fn unknown_magic(magic: [i8; 4]) -> Self {
let inner = Inner::UnknownMagic { magic };
Self(inner)
}
}
impl Display for DecodeError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self.0 {
Inner::EndOfFile { found, expected } => {
write!(f, "wad file of `{found}` byte(s) may not be smaller than `{expected}` byte(s)")?;
}
#[cfg(feature = "std")]
Inner::Io(ref e) => {
write!(f, "{e}")?;
}
Inner::LargeSize { temporary } => {
write!(f, "computed size value `{temporary}` cannot be represented")?;
}
Inner::UnknownMagic { ref magic } => {
write!(f, "magic `{}` is unknown or unsupported", magic.as_octs().escape_ascii())?;
}
}
Ok(())
}
}
impl Error for DecodeError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self.0 {
#[cfg(feature = "std")]
Inner::Io(ref e) => Some(e),
_ => None,
}
}
}
#[cfg(feature = "std")]
impl From<io::Error> for DecodeError {
#[inline]
fn from(value: io::Error) -> Self {
let inner = Inner::Io(value);
Self(inner)
}
}
impl From<Infallible> for DecodeError {
fn from(value: Infallible) -> Self {
match value {}
}
}
#[derive(Debug)]
enum Inner {
EndOfFile {
found: usize,
expected: usize,
},
#[cfg(feature = "std")]
Io(io::Error),
LargeSize {
temporary: u64,
},
UnknownMagic {
magic: [i8; 4],
},
}