use alloc::string::String;
use thiserror::Error;
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum AfpError {
#[error("audio too short: needed at least {needed} samples, got {got}")]
AudioTooShort {
needed: usize,
got: usize,
},
#[error("unsupported sample rate: {0} Hz (supported: 8000, 11025, 16000, 22050, 44100, 48000)")]
UnsupportedSampleRate(u32),
#[error("unsupported channel count: {0}")]
UnsupportedChannels(u16),
#[error("model not found at {0}")]
ModelNotFound(String),
#[error("model load failed: {0}")]
ModelLoad(String),
#[error("inference failed: {0}")]
Inference(String),
#[error("buffer overrun: dropped {dropped} samples")]
BufferOverrun {
dropped: usize,
},
#[error("invalid configuration: {0}")]
Config(String),
#[error("io: {0}")]
Io(String),
}
pub type Result<T> = core::result::Result<T, AfpError>;
#[cfg(test)]
mod tests {
use super::*;
use alloc::string::ToString;
#[test]
fn audio_too_short_displays_both_numbers() {
let e = AfpError::AudioTooShort {
needed: 16_000,
got: 8_000,
};
let s = e.to_string();
assert!(s.contains("16000"), "got: {s}");
assert!(s.contains("8000"), "got: {s}");
}
#[test]
fn unsupported_sample_rate_shows_value_and_supported_list() {
let s = AfpError::UnsupportedSampleRate(7_000).to_string();
assert!(s.contains("7000"));
for rate in ["8000", "11025", "16000", "22050", "44100", "48000"] {
assert!(s.contains(rate), "missing {rate} in: {s}");
}
}
#[test]
fn buffer_overrun_reports_drop_count() {
let s = AfpError::BufferOverrun { dropped: 1024 }.to_string();
assert!(s.contains("1024"));
}
#[test]
fn result_ok_path() {
let f = |x: u32| -> Result<u32> { Ok(x * 2) };
assert_eq!(f(21).unwrap(), 42);
}
}