use thiserror::Error;
#[derive(Debug, Clone, PartialEq, Eq, Error)]
pub enum CodecError {
#[error("I/O error: {0}")]
Io(String),
#[error("unsupported or unrecognised format: {0}")]
Format(String),
#[error("decode error: {0}")]
Decode(String),
#[error("end of stream")]
Eof,
#[error("invalid sample rate: {0} Hz")]
InvalidSampleRate(u32),
#[error("invalid channel count: {0}")]
InvalidChannelCount(u16),
#[error("buffer too small: needed {needed} samples, have {have}")]
BufferTooSmall {
needed: usize,
have: usize,
},
}
pub type Result<T> = core::result::Result<T, CodecError>;
#[cfg(test)]
mod tests {
use super::{CodecError, Result};
#[test]
fn io_display_includes_message() {
let msg = CodecError::Io("permission denied".into()).to_string();
assert_eq!(msg, "I/O error: permission denied");
}
#[test]
fn format_display_includes_message() {
let msg = CodecError::Format("unknown magic bytes".into()).to_string();
assert_eq!(
msg,
"unsupported or unrecognised format: unknown magic bytes"
);
}
#[test]
fn decode_display_includes_message() {
let msg = CodecError::Decode("truncated frame".into()).to_string();
assert_eq!(msg, "decode error: truncated frame");
}
#[test]
fn eof_display_is_stable() {
assert_eq!(CodecError::Eof.to_string(), "end of stream");
}
#[test]
fn invalid_sample_rate_display_includes_value() {
let msg = CodecError::InvalidSampleRate(0).to_string();
assert_eq!(msg, "invalid sample rate: 0 Hz");
}
#[test]
fn invalid_channel_count_display_includes_value() {
let msg = CodecError::InvalidChannelCount(7).to_string();
assert_eq!(msg, "invalid channel count: 7");
}
#[test]
fn buffer_too_small_display_includes_both_counts() {
let msg = CodecError::BufferTooSmall {
needed: 100,
have: 50,
}
.to_string();
assert_eq!(msg, "buffer too small: needed 100 samples, have 50");
}
#[test]
fn result_alias_ok_carries_value() {
let ok: Result<u32> = Ok(42);
assert_eq!(ok.map(|v| v + 1), Ok(43));
}
#[test]
fn result_alias_err_carries_codec_error() {
let err: Result<u32> = Err(CodecError::InvalidChannelCount(0));
assert_eq!(err.err(), Some(CodecError::InvalidChannelCount(0)));
}
#[test]
fn clone_and_partial_eq_hold_across_variants() {
let a = CodecError::BufferTooSmall { needed: 2, have: 1 };
assert_eq!(a.clone(), a);
assert_ne!(
CodecError::InvalidSampleRate(1),
CodecError::InvalidChannelCount(1),
);
assert_eq!(CodecError::Io("x".into()), CodecError::Io("x".into()),);
}
}