use std::borrow::Cow;
use std::{error, fmt, io};
use crate::Fourcc;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)]
pub enum ErrorKind {
AtomNotFound(Fourcc),
DescriptorNotFound(u8),
NoFtyp,
InvalidAtomSize,
SizeMismatch,
AtomSizeOutOfBounds,
InvalidSampleTable,
UnknownChannelConfig(u8),
UnknownMediaType(u8),
UnknownSampleRate(u8),
UnknownVersion(u8),
Utf8StringDecoding,
Utf16StringDecoding,
Io(io::Error),
}
pub struct Error {
pub kind: ErrorKind,
pub description: Cow<'static, str>,
}
impl Error {
pub fn new(kind: ErrorKind, description: impl Into<Cow<'static, str>>) -> Error {
Error { kind, description: description.into() }
}
}
impl error::Error for Error {
fn cause(&self) -> Option<&dyn error::Error> {
match self.kind {
ErrorKind::Io(ref err) => Some(err),
_ => None,
}
}
}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Error {
let description = format!("IO error: {err}");
Error::new(ErrorKind::Io(err), description)
}
}
impl fmt::Debug for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.description.is_empty() {
write!(f, "{:?}", self.kind)
} else {
write!(f, "{}:\n{:?}", self.description, self.kind)
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.description.is_empty() {
write!(f, "{:?}", self.kind)
} else {
write!(f, "{}:\n{:?}", self.description, self.kind)
}
}
}