stream-wave-parser 0.1.2

The `stream-wave-parser` is a crate that treats a stream from WAVE file.
Documentation
//! Types to represent errors in `stream-wave-parser`.

/// A specialized `Result` type for `stream-wave-parser`.
pub type Result<T> = std::result::Result<T, Error>;

type BoxError = Box<dyn std::error::Error + Send + Sync>;

/// The error type for `stream-wave-parser`.
pub enum Error {
    /// The data does not begin `RIFF`.
    RiffChunkHeaderIsNotFound,

    /// The RIFF data does not have a `WAVE` chunk.
    WaveChunkHeaderIsNotFound,

    /// The RIFF WAVE data does not have a `fmt ` chunk before `data` chunk.
    FmtChunkIsNotFound,

    /// The length of `data` chunk is not enough for the amount that represented by the `length` field.
    DataIsNotEnough,

    /// The [`WaveChannelMixer`][`crate::WaveChannelMixer`] is only support PCM integer (`pcm_format` is 1).
    MixerConstruction(&'static str),

    /// The user defined type created by [`Error::custom()`].
    Custom(BoxError),
}

impl Error {
    /// Creates [`Error::Custom`].
    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."
        );
    }
}