pub type Result<T> = std::result::Result<T, Error>;
type BoxError = Box<dyn std::error::Error + Send + Sync>;
pub enum Error {
RiffChunkHeaderIsNotFound,
WaveChunkHeaderIsNotFound,
FmtChunkIsNotFound,
DataIsNotEnough,
MixerConstruction(&'static str),
Custom(BoxError),
}
impl Error {
pub fn custom(e: impl std::error::Error + Send + Sync + 'static) -> Self {
Self::Custom(Box::new(e))
}
}
impl std::error::Error for Error {}
impl std::fmt::Debug for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
if let Self::Custom(e) = self {
return format!("custom: {e:?}").fmt(f);
}
<Self as std::fmt::Display>::fmt(self, f)
}
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
use Error::*;
match self {
RiffChunkHeaderIsNotFound => "`RIFF` label is not found.".fmt(f),
WaveChunkHeaderIsNotFound => "`WAVE` label is not found.".fmt(f),
FmtChunkIsNotFound => "`fmt ` label is not found.".fmt(f),
DataIsNotEnough => "data is not enough.".fmt(f),
MixerConstruction(reason) => {
for msg in ["failed to construct a `WaveChannelMixer`: ", reason, "."] {
msg.fmt(f)?;
}
Ok(())
}
Custom(e) => format!("custom: {e}.").fmt(f),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_fmt() {
assert_eq!(
format!("{}", Error::MixerConstruction("foo")),
"failed to construct a `WaveChannelMixer`: foo."
);
}
}