samplerate_rs/
error.rs

1use libsamplerate::*;
2use std::ffi::CStr;
3
4#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
5pub enum ErrorCode {
6    Unknown = -1,
7    NoError = 0,
8    MallocFailed = 1,
9    BadState = 2,
10    BadData = 3,
11    BadDataPtr = 4,
12    NoPrivate = 5,
13    BadSrcRatio = 6,
14    BadProcPtr = 7,
15    ShiftBits = 8,
16    FilterLen = 9,
17    BadConverter = 10,
18    BadChannelCount = 11,
19    SincBadBufferLen = 12,
20    SizeIncompatibility = 13,
21    BadPrivPtr = 14,
22    BadSincState = 15,
23    DataOverlap = 16,
24    BadCallback = 17,
25    BadMode = 18,
26    NullCallback = 19,
27    NoVariableRatio = 20,
28    SincPrepareDataBadLen = 21,
29    BadInternalState = 22,
30    MaxError = 23,
31}
32
33impl ErrorCode {
34    /// Create a new `ConverterType` enum from the corresponding integer.
35    pub fn from_int(value: i32) -> ErrorCode {
36        match value {
37            0 => ErrorCode::NoError,
38            1 => ErrorCode::MallocFailed,
39            2 => ErrorCode::BadState,
40            3 => ErrorCode::BadData,
41            4 => ErrorCode::BadDataPtr,
42            5 => ErrorCode::NoPrivate,
43            6 => ErrorCode::BadSrcRatio,
44            7 => ErrorCode::BadProcPtr,
45            8 => ErrorCode::ShiftBits,
46            9 => ErrorCode::FilterLen,
47            10 => ErrorCode::BadConverter,
48            11 => ErrorCode::BadChannelCount,
49            12 => ErrorCode::SincBadBufferLen,
50            13 => ErrorCode::SizeIncompatibility,
51            14 => ErrorCode::BadPrivPtr,
52            15 => ErrorCode::BadSincState,
53            16 => ErrorCode::DataOverlap,
54            17 => ErrorCode::BadCallback,
55            18 => ErrorCode::BadMode,
56            19 => ErrorCode::NullCallback,
57            20 => ErrorCode::NoVariableRatio,
58            21 => ErrorCode::SincPrepareDataBadLen,
59            22 => ErrorCode::BadInternalState,
60            23 => ErrorCode::MaxError,
61            _ => ErrorCode::Unknown,
62        }
63    }
64
65    /// Return the human-readable description for this error.
66    pub fn description(&self) -> &'static str {
67        match self {
68            ErrorCode::Unknown => "Unkown error.",
69            _ => unsafe { CStr::from_ptr(src_strerror(*self as i32)) }
70                .to_str()
71                .unwrap(),
72        }
73    }
74}
75
76#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
77pub struct Error {
78    code: ErrorCode,
79}
80
81impl Error {
82    pub fn from_int(code: i32) -> Error {
83        Error {
84            code: ErrorCode::from_int(code),
85        }
86    }
87
88    pub fn from_code(code: ErrorCode) -> Error {
89        Error { code }
90    }
91
92    pub fn code(&self) -> ErrorCode {
93        self.code
94    }
95
96    pub fn description(&self) -> &'static str {
97        self.code.description()
98    }
99}
100
101impl std::fmt::Display for Error {
102    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
103        write!(f, "{}", self.description())
104    }
105}
106
107impl std::error::Error for Error {
108    fn description(&self) -> &str {
109        &self.code.description()
110    }
111}
112
113#[cfg(test)]
114mod tests {
115    use super::*;
116
117    #[test]
118    fn create_converter_type_from_int() {
119        assert_eq!(ErrorCode::from_int(0), ErrorCode::NoError);
120        assert_eq!(ErrorCode::from_int(1), ErrorCode::MallocFailed);
121        assert_eq!(ErrorCode::from_int(2), ErrorCode::BadState);
122        assert_eq!(ErrorCode::from_int(3), ErrorCode::BadData);
123        assert_eq!(ErrorCode::from_int(4), ErrorCode::BadDataPtr);
124        assert_eq!(ErrorCode::from_int(5), ErrorCode::NoPrivate);
125        assert_eq!(ErrorCode::from_int(6), ErrorCode::BadSrcRatio);
126        assert_eq!(ErrorCode::from_int(7), ErrorCode::BadProcPtr);
127        assert_eq!(ErrorCode::from_int(8), ErrorCode::ShiftBits);
128        assert_eq!(ErrorCode::from_int(9), ErrorCode::FilterLen);
129        assert_eq!(ErrorCode::from_int(10), ErrorCode::BadConverter);
130        assert_eq!(ErrorCode::from_int(11), ErrorCode::BadChannelCount);
131        assert_eq!(ErrorCode::from_int(12), ErrorCode::SincBadBufferLen);
132        assert_eq!(ErrorCode::from_int(13), ErrorCode::SizeIncompatibility);
133        assert_eq!(ErrorCode::from_int(14), ErrorCode::BadPrivPtr);
134        assert_eq!(ErrorCode::from_int(15), ErrorCode::BadSincState);
135        assert_eq!(ErrorCode::from_int(16), ErrorCode::DataOverlap);
136        assert_eq!(ErrorCode::from_int(17), ErrorCode::BadCallback);
137        assert_eq!(ErrorCode::from_int(18), ErrorCode::BadMode);
138        assert_eq!(ErrorCode::from_int(19), ErrorCode::NullCallback);
139        assert_eq!(ErrorCode::from_int(20), ErrorCode::NoVariableRatio);
140        assert_eq!(ErrorCode::from_int(21), ErrorCode::SincPrepareDataBadLen);
141        assert_eq!(ErrorCode::from_int(22), ErrorCode::BadInternalState);
142        assert_eq!(ErrorCode::from_int(23), ErrorCode::MaxError);
143        assert_eq!(ErrorCode::from_int(24), ErrorCode::Unknown);
144    }
145
146    #[test]
147    fn description() {
148        assert_eq!(ErrorCode::NoError.description(), "No error.");
149        assert_eq!(ErrorCode::MallocFailed.description(), "Malloc failed.");
150        assert_eq!(
151            ErrorCode::BadState.description(),
152            "SRC_STATE pointer is NULL."
153        );
154        assert_eq!(
155            ErrorCode::BadData.description(),
156            "SRC_DATA pointer is NULL."
157        );
158        assert_eq!(
159            ErrorCode::BadDataPtr.description(),
160            "SRC_DATA->data_out or SRC_DATA->data_in is NULL."
161        );
162        assert_eq!(
163            ErrorCode::NoPrivate.description(),
164            "Internal error. No private data."
165        );
166        assert_eq!(
167            ErrorCode::BadSrcRatio.description(),
168            "SRC ratio outside [1/256, 256] range."
169        );
170        assert_eq!(
171            ErrorCode::BadSincState.description(),
172            "src_process() called without reset after end_of_input."
173        );
174        assert_eq!(
175            ErrorCode::BadProcPtr.description(),
176            "Internal error. No process pointer."
177        );
178        assert_eq!(
179            ErrorCode::ShiftBits.description(),
180            "Internal error. SHIFT_BITS too large."
181        );
182        assert_eq!(
183            ErrorCode::FilterLen.description(),
184            "Internal error. Filter length too large."
185        );
186        assert_eq!(
187            ErrorCode::BadConverter.description(),
188            "Bad converter number."
189        );
190        assert_eq!(
191            ErrorCode::BadChannelCount.description(),
192            "Channel count must be >= 1."
193        );
194        assert_eq!(
195            ErrorCode::SincBadBufferLen.description(),
196            "Internal error. Bad buffer length. Please report this."
197        );
198        assert_eq!(
199            ErrorCode::SizeIncompatibility.description(),
200            "Internal error. Input data / internal buffer size difference. Please report this."
201        );
202        assert_eq!(
203            ErrorCode::BadPrivPtr.description(),
204            "Internal error. Private pointer is NULL. Please report this."
205        );
206        assert_eq!(
207            ErrorCode::DataOverlap.description(),
208            "Input and output data arrays overlap."
209        );
210        assert_eq!(
211            ErrorCode::BadCallback.description(),
212            "Supplied callback function pointer is NULL."
213        );
214        assert_eq!(
215            ErrorCode::BadMode.description(),
216            "Calling mode differs from initialisation mode (ie process v callback)."
217        );
218        assert_eq!(
219            ErrorCode::NullCallback.description(),
220            "Callback function pointer is NULL in src_callback_read ()."
221        );
222        assert_eq!(
223            ErrorCode::NoVariableRatio.description(),
224            "This converter only allows constant conversion ratios."
225        );
226        assert_eq!(
227            ErrorCode::SincPrepareDataBadLen.description(),
228            "Internal error : Bad length in prepare_data ()."
229        );
230        assert_eq!(
231            ErrorCode::BadInternalState.description(),
232            "Error : Someone is trampling on my internal state."
233        );
234        assert_eq!(
235            ErrorCode::MaxError.description(),
236            "Placeholder. No error defined for this error number."
237        );
238        assert_eq!(ErrorCode::Unknown.description(), "Unkown error.");
239    }
240
241    #[test]
242    fn error_from_code_and_int() {
243        assert_eq!(Error::from_int(2), Error::from_code(ErrorCode::BadState));
244    }
245
246    #[test]
247    fn error_description() {
248        for i in -1..24 {
249            assert_eq!(
250                Error::from_int(i).description(),
251                ErrorCode::from_int(i).description()
252            );
253        }
254    }
255}