audio_resample_bsd/
error.rs1use thiserror::Error;
9
10#[derive(Debug, Clone, PartialEq, Error)]
12pub enum ResampleError {
13 #[error("invalid sample rate: {rate} Hz")]
15 InvalidSampleRate {
16 rate: f64,
18 },
19
20 #[error("invalid channel count: {0}")]
22 InvalidChannelCount(usize),
23
24 #[error("invalid chunk size: {0}")]
26 InvalidChunkSize(usize),
27
28 #[error("buffer too small: needed {needed} samples, have {have}")]
30 BufferTooSmall {
31 needed: usize,
33 have: usize,
35 },
36
37 #[error("input length mismatch: expected {expected} samples, got {actual}")]
40 InputLengthMismatch {
41 expected: usize,
43 actual: usize,
45 },
46
47 #[error("resample failed: {0}")]
50 ResampleFailed(String),
51
52 #[error(transparent)]
54 Core(#[from] audio_core_bsd::AudioError),
55}
56
57pub type Result<T> = core::result::Result<T, ResampleError>;
59
60#[cfg(test)]
61mod tests {
62 use super::{ResampleError, Result};
63
64 #[test]
65 fn invalid_sample_rate_display_includes_value() {
66 let msg = ResampleError::InvalidSampleRate { rate: 0.0 }.to_string();
67 assert_eq!(msg, "invalid sample rate: 0 Hz");
68 }
69
70 #[test]
71 fn invalid_channel_count_display_includes_value() {
72 let msg = ResampleError::InvalidChannelCount(0).to_string();
73 assert_eq!(msg, "invalid channel count: 0");
74 }
75
76 #[test]
77 fn invalid_chunk_size_display_includes_value() {
78 let msg = ResampleError::InvalidChunkSize(0).to_string();
79 assert_eq!(msg, "invalid chunk size: 0");
80 }
81
82 #[test]
83 fn buffer_too_small_display_includes_both_counts() {
84 let msg = ResampleError::BufferTooSmall {
85 needed: 100,
86 have: 50,
87 }
88 .to_string();
89 assert_eq!(msg, "buffer too small: needed 100 samples, have 50");
90 }
91
92 #[test]
93 fn input_length_mismatch_display_includes_both_counts() {
94 let msg = ResampleError::InputLengthMismatch {
95 expected: 1024,
96 actual: 512,
97 }
98 .to_string();
99 assert_eq!(msg, "input length mismatch: expected 1024 samples, got 512",);
100 }
101
102 #[test]
103 fn resample_failed_display_wraps_message() {
104 let msg = ResampleError::ResampleFailed("rubato internal".to_string()).to_string();
105 assert_eq!(msg, "resample failed: rubato internal");
106 }
107
108 #[test]
109 fn core_variant_derives_from_audio_error() {
110 let core_err = audio_core_bsd::AudioError::InvalidChannelCount(0);
111 let resampled: ResampleError = core_err.into();
112 let msg = resampled.to_string();
113 assert_eq!(msg, "invalid channel count: 0");
116 }
117
118 #[test]
119 fn result_alias_ok_carries_value() {
120 let ok: Result<u32> = Ok(42);
121 assert_eq!(ok.map(|v| v + 1), Ok(43));
122 }
123
124 #[test]
125 fn result_alias_err_carries_resample_error() {
126 let err: Result<u32> = Err(ResampleError::InvalidChannelCount(0));
127 assert_eq!(err.err(), Some(ResampleError::InvalidChannelCount(0)));
128 }
129
130 #[test]
131 fn clone_and_partial_eq_hold_across_variants() {
132 let a = ResampleError::BufferTooSmall { needed: 2, have: 1 };
133 assert_eq!(a.clone(), a);
134 assert_ne!(
136 ResampleError::InvalidChannelCount(1),
137 ResampleError::InvalidChunkSize(1),
138 );
139 }
140
141 #[test]
142 fn resample_failed_clone_preserves_message() {
143 let a = ResampleError::ResampleFailed("boom".to_string());
144 let b = a.clone();
145 assert_eq!(a, b);
146 }
147}