use core::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum InvalidData {
FileSignature,
HeaderLength,
CopyrightSignature,
SampleCount(u32),
FrameHeader,
GroupedQuantizer,
FrameLength,
EndMarker,
}
impl fmt::Display for InvalidData {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::FileSignature => f.write_str("file signature"),
Self::HeaderLength => f.write_str("header length"),
Self::CopyrightSignature => f.write_str("copyright signature"),
Self::SampleCount(count) => write!(f, "declared sample count {count}"),
Self::FrameHeader => f.write_str("MPEG frame header"),
Self::GroupedQuantizer => f.write_str("grouped quantizer"),
Self::FrameLength => f.write_str("frame length"),
Self::EndMarker => f.write_str("end marker"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum UnsupportedData {
Profile,
SampleRate(u32),
}
impl fmt::Display for UnsupportedData {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Profile => f.write_str("expected unencrypted mono type 0x10 version 6"),
Self::SampleRate(rate) => write!(f, "declared sample rate {rate} Hz"),
}
}
}
#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
Truncated,
Unsupported(UnsupportedData),
Invalid(InvalidData),
Failed,
BufferTooSmall {
required: usize,
provided: usize,
},
#[cfg(feature = "std")]
Io(std::io::Error),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Truncated => f.write_str("truncated AHX data"),
Self::Unsupported(reason) => write!(f, "unsupported AHX: {reason}"),
Self::Invalid(reason) => write!(f, "invalid AHX: {reason}"),
Self::Failed => f.write_str("AHX decoder cannot continue after an error"),
Self::BufferTooSmall { required, provided } => write!(
f,
"PCM buffer needs {required} i16 elements, received {provided}"
),
#[cfg(feature = "std")]
Self::Io(error) => error.fmt(f),
}
}
}
impl core::error::Error for Error {
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
#[cfg(feature = "std")]
if let Self::Io(error) = self {
return Some(error);
}
None
}
}
#[cfg(feature = "std")]
impl From<std::io::Error> for Error {
fn from(error: std::io::Error) -> Self {
if error.kind() == std::io::ErrorKind::UnexpectedEof {
Self::Truncated
} else {
Self::Io(error)
}
}
}
pub(crate) type Result<T> = core::result::Result<T, Error>;