1use core::fmt;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5#[non_exhaustive]
6pub enum InvalidData {
7 FileSignature,
9 HeaderLength,
11 CopyrightSignature,
13 SampleCount(u32),
15 FrameHeader,
17 GroupedQuantizer,
19 FrameLength,
21 EndMarker,
23}
24
25impl fmt::Display for InvalidData {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 match self {
28 Self::FileSignature => f.write_str("file signature"),
29 Self::HeaderLength => f.write_str("header length"),
30 Self::CopyrightSignature => f.write_str("copyright signature"),
31 Self::SampleCount(count) => write!(f, "declared sample count {count}"),
32 Self::FrameHeader => f.write_str("MPEG frame header"),
33 Self::GroupedQuantizer => f.write_str("grouped quantizer"),
34 Self::FrameLength => f.write_str("frame length"),
35 Self::EndMarker => f.write_str("end marker"),
36 }
37 }
38}
39
40#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42#[non_exhaustive]
43pub enum UnsupportedData {
44 Profile,
46 SampleRate(u32),
48}
49
50impl fmt::Display for UnsupportedData {
51 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52 match self {
53 Self::Profile => f.write_str("expected unencrypted mono type 0x10 version 6"),
54 Self::SampleRate(rate) => write!(f, "declared sample rate {rate} Hz"),
55 }
56 }
57}
58
59#[derive(Debug)]
61#[non_exhaustive]
62pub enum Error {
63 Truncated,
65 Unsupported(UnsupportedData),
67 Invalid(InvalidData),
69 Failed,
71 BufferTooSmall {
73 required: usize,
75 provided: usize,
77 },
78 #[cfg(feature = "std")]
80 Io(std::io::Error),
81}
82
83impl fmt::Display for Error {
84 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85 match self {
86 Self::Truncated => f.write_str("truncated AHX data"),
87 Self::Unsupported(reason) => write!(f, "unsupported AHX: {reason}"),
88 Self::Invalid(reason) => write!(f, "invalid AHX: {reason}"),
89 Self::Failed => f.write_str("AHX decoder cannot continue after an error"),
90 Self::BufferTooSmall { required, provided } => write!(
91 f,
92 "PCM buffer needs {required} i16 elements, received {provided}"
93 ),
94 #[cfg(feature = "std")]
95 Self::Io(error) => error.fmt(f),
96 }
97 }
98}
99
100impl core::error::Error for Error {
101 fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
102 #[cfg(feature = "std")]
103 if let Self::Io(error) = self {
104 return Some(error);
105 }
106 None
107 }
108}
109
110#[cfg(feature = "std")]
111impl From<std::io::Error> for Error {
112 fn from(error: std::io::Error) -> Self {
113 if error.kind() == std::io::ErrorKind::UnexpectedEof {
114 Self::Truncated
115 } else {
116 Self::Io(error)
117 }
118 }
119}
120
121pub(crate) type Result<T> = core::result::Result<T, Error>;