1use thiserror::Error;
4
5#[derive(Debug, Clone, PartialEq, Eq, Error)]
11pub enum CodecError {
12 #[error("I/O error: {0}")]
14 Io(String),
15
16 #[error("unsupported or unrecognised format: {0}")]
18 Format(String),
19
20 #[error("decode error: {0}")]
22 Decode(String),
23
24 #[error("end of stream")]
30 Eof,
31
32 #[error("invalid sample rate: {0} Hz")]
34 InvalidSampleRate(u32),
35
36 #[error("invalid channel count: {0}")]
38 InvalidChannelCount(u16),
39
40 #[error("buffer too small: needed {needed} samples, have {have}")]
42 BufferTooSmall {
43 needed: usize,
45 have: usize,
47 },
48}
49
50pub type Result<T> = core::result::Result<T, CodecError>;
52
53#[cfg(test)]
54mod tests {
55 use super::{CodecError, Result};
56
57 #[test]
58 fn io_display_includes_message() {
59 let msg = CodecError::Io("permission denied".into()).to_string();
60 assert_eq!(msg, "I/O error: permission denied");
61 }
62
63 #[test]
64 fn format_display_includes_message() {
65 let msg = CodecError::Format("unknown magic bytes".into()).to_string();
66 assert_eq!(
67 msg,
68 "unsupported or unrecognised format: unknown magic bytes"
69 );
70 }
71
72 #[test]
73 fn decode_display_includes_message() {
74 let msg = CodecError::Decode("truncated frame".into()).to_string();
75 assert_eq!(msg, "decode error: truncated frame");
76 }
77
78 #[test]
79 fn eof_display_is_stable() {
80 assert_eq!(CodecError::Eof.to_string(), "end of stream");
81 }
82
83 #[test]
84 fn invalid_sample_rate_display_includes_value() {
85 let msg = CodecError::InvalidSampleRate(0).to_string();
86 assert_eq!(msg, "invalid sample rate: 0 Hz");
87 }
88
89 #[test]
90 fn invalid_channel_count_display_includes_value() {
91 let msg = CodecError::InvalidChannelCount(7).to_string();
92 assert_eq!(msg, "invalid channel count: 7");
93 }
94
95 #[test]
96 fn buffer_too_small_display_includes_both_counts() {
97 let msg = CodecError::BufferTooSmall {
98 needed: 100,
99 have: 50,
100 }
101 .to_string();
102 assert_eq!(msg, "buffer too small: needed 100 samples, have 50");
103 }
104
105 #[test]
106 fn result_alias_ok_carries_value() {
107 let ok: Result<u32> = Ok(42);
108 assert_eq!(ok.map(|v| v + 1), Ok(43));
109 }
110
111 #[test]
112 fn result_alias_err_carries_codec_error() {
113 let err: Result<u32> = Err(CodecError::InvalidChannelCount(0));
114 assert_eq!(err.err(), Some(CodecError::InvalidChannelCount(0)));
115 }
116
117 #[test]
118 fn clone_and_partial_eq_hold_across_variants() {
119 let a = CodecError::BufferTooSmall { needed: 2, have: 1 };
120 assert_eq!(a.clone(), a);
121 assert_ne!(
123 CodecError::InvalidSampleRate(1),
124 CodecError::InvalidChannelCount(1),
125 );
126 assert_eq!(CodecError::Io("x".into()), CodecError::Io("x".into()),);
128 }
129}