coreaudio/
error.rs

1//! This module is an attempt at rustifying the OSStatus result.
2
3pub use self::audio::Error as AudioError;
4pub use self::audio_codec::Error as AudioCodecError;
5pub use self::audio_format::Error as AudioFormatError;
6pub use self::audio_unit::Error as AudioUnitError;
7use crate::OSStatus;
8
9pub mod audio {
10    use crate::OSStatus;
11
12    #[derive(Copy, Clone, Debug)]
13    pub enum Error {
14        Unimplemented = -4,
15        FileNotFound = -43,
16        FilePermission = -54,
17        TooManyFilesOpen = -42,
18        BadFilePath = 561017960,
19        Param = -50,
20        MemFull = -108,
21        Unknown,
22    }
23
24    impl Error {
25        pub fn from_os_status(os_status: OSStatus) -> Result<(), Error> {
26            match os_status {
27                0 => Ok(()),
28                -4 => Err(Error::Unimplemented),
29                -43 => Err(Error::FileNotFound),
30                -54 => Err(Error::FilePermission),
31                -42 => Err(Error::TooManyFilesOpen),
32                561017960 => Err(Error::BadFilePath),
33                -50 => Err(Error::Param),
34                -108 => Err(Error::MemFull),
35                _ => Err(Error::Unknown),
36            }
37        }
38
39        pub fn as_os_status(&self) -> OSStatus {
40            *self as OSStatus
41        }
42    }
43
44    impl std::error::Error for Error {}
45
46    impl ::std::fmt::Display for Error {
47        fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
48            let description = match *self {
49                Error::Unimplemented => "Unimplemented",
50                Error::FileNotFound => "File not found",
51                Error::FilePermission => "File permission",
52                Error::TooManyFilesOpen => "Too many files open",
53                Error::BadFilePath => "Bad file path",
54                Error::Param => "Param",
55                Error::MemFull => "Memory full",
56                Error::Unknown => "An unknown error occurred",
57            };
58            write!(f, "{}", description)
59        }
60    }
61}
62
63pub mod audio_codec {
64    use crate::OSStatus;
65
66    #[derive(Copy, Clone, Debug)]
67    pub enum Error {
68        Unspecified = 2003329396,
69        UnknownProperty = 2003332927,
70        BadPropertySize = 561211770,
71        IllegalOperation = 1852797029,
72        UnsupportedFormat = 560226676,
73        State = 561214580,
74        NotEnoughBufferSpace = 560100710,
75        Unknown,
76    }
77
78    impl Error {
79        pub fn from_os_status(os_status: OSStatus) -> Result<(), Error> {
80            match os_status {
81                0 => Ok(()),
82                2003329396 => Err(Error::Unspecified),
83                2003332927 => Err(Error::UnknownProperty),
84                561211770 => Err(Error::BadPropertySize),
85                1852797029 => Err(Error::IllegalOperation),
86                560226676 => Err(Error::UnsupportedFormat),
87                561214580 => Err(Error::State),
88                560100710 => Err(Error::NotEnoughBufferSpace),
89                _ => Err(Error::Unknown),
90            }
91        }
92
93        pub fn as_os_status(&self) -> OSStatus {
94            *self as OSStatus
95        }
96    }
97
98    impl std::error::Error for Error {}
99
100    impl ::std::fmt::Display for Error {
101        fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
102            let description = match *self {
103                Error::Unspecified => "Unspecified",
104                Error::UnknownProperty => "Unknown property",
105                Error::BadPropertySize => "Bad property size",
106                Error::IllegalOperation => "Illegal operation",
107                Error::UnsupportedFormat => "Unsupported format",
108                Error::State => "State",
109                Error::NotEnoughBufferSpace => "Not enough buffer space",
110                Error::Unknown => "Unknown error occurred",
111            };
112            write!(f, "{}", description)
113        }
114    }
115}
116
117pub mod audio_format {
118    use crate::OSStatus;
119
120    // TODO: Finish implementing these values.
121    #[derive(Copy, Clone, Debug)]
122    pub enum Error {
123        Unspecified,                        // 'what'
124        UnsupportedProperty,                // 'prop'
125        BadPropertySize,                    // '!siz'
126        BadSpecifierSize,                   // '!spc'
127        UnsupportedDataFormat = 1718449215, // 'fmt?'
128        UnknownFormat,                      // '!fmt'
129        Unknown,                            //
130    }
131
132    impl Error {
133        pub fn from_os_status(os_status: OSStatus) -> Result<(), Error> {
134            match os_status {
135                0 => Ok(()),
136                1718449215 => Err(Error::UnsupportedDataFormat),
137                _ => Err(Error::Unknown),
138            }
139        }
140
141        pub fn as_os_status(&self) -> OSStatus {
142            *self as OSStatus
143        }
144    }
145
146    impl std::error::Error for Error {}
147
148    impl ::std::fmt::Display for Error {
149        fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
150            let description = match *self {
151                Error::Unspecified => "An unspecified error",
152                Error::UnsupportedProperty => "The specified property is not supported",
153                Error::BadPropertySize => "Bad property size",
154                Error::BadSpecifierSize => "Bad specifier size",
155                Error::UnsupportedDataFormat => "The specified data format is not supported",
156                Error::UnknownFormat => "The specified data format is not a known format",
157                Error::Unknown => "Unknown error occurred",
158            };
159            write!(f, "{}", description)
160        }
161    }
162}
163
164pub mod audio_unit {
165    use crate::OSStatus;
166
167    #[derive(Copy, Clone, Debug)]
168    pub enum Error {
169        InvalidProperty = -10879,
170        InvalidParameter = -10878,
171        InvalidElement = -10877,
172        NoConnection = -10876,
173        FailedInitialization = -10875,
174        TooManyFramesToProcess = -10874,
175        InvalidFile = -10871,
176        FormatNotSupported = -10868,
177        Uninitialized = -10867,
178        InvalidScope = -10866,
179        PropertyNotWritable = -10865,
180        CannotDoInCurrentContext = -10863,
181        InvalidPropertyValue = -10851,
182        PropertyNotInUse = -10850,
183        Initialized = -10849,
184        InvalidOfflineRender = -10848,
185        Unauthorized = -10847,
186        Unknown,
187    }
188
189    impl Error {
190        pub fn from_os_status(os_status: OSStatus) -> Result<(), Error> {
191            match os_status {
192                -10879 => Err(Error::InvalidProperty),
193                -10878 => Err(Error::InvalidParameter),
194                -10877 => Err(Error::InvalidElement),
195                -10876 => Err(Error::NoConnection),
196                -10875 => Err(Error::FailedInitialization),
197                -10874 => Err(Error::TooManyFramesToProcess),
198                -10871 => Err(Error::InvalidFile),
199                -10868 => Err(Error::FormatNotSupported),
200                -10867 => Err(Error::Uninitialized),
201                -10866 => Err(Error::InvalidScope),
202                -10865 => Err(Error::PropertyNotWritable),
203                -10863 => Err(Error::CannotDoInCurrentContext),
204                -10851 => Err(Error::InvalidPropertyValue),
205                -10850 => Err(Error::PropertyNotInUse),
206                -10849 => Err(Error::Initialized),
207                -10848 => Err(Error::InvalidOfflineRender),
208                -10847 => Err(Error::Unauthorized),
209                _ => Err(Error::Unknown),
210            }
211        }
212
213        pub fn as_os_status(&self) -> OSStatus {
214            *self as OSStatus
215        }
216    }
217
218    impl std::error::Error for Error {}
219
220    impl ::std::fmt::Display for Error {
221        fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
222            let description = match *self {
223                Error::InvalidProperty => "Invalid property",
224                Error::InvalidParameter => "Invalid parameter",
225                Error::InvalidElement => "Invalid element",
226                Error::NoConnection => "No connection",
227                Error::FailedInitialization => "Failed initialization",
228                Error::TooManyFramesToProcess => "Too many frames to process",
229                Error::InvalidFile => "Invalid file",
230                Error::FormatNotSupported => "Format not supported",
231                Error::Uninitialized => "Uninitialized",
232                Error::InvalidScope => "Invalid scope",
233                Error::PropertyNotWritable => "Property not writable",
234                Error::CannotDoInCurrentContext => "Cannot do in current context",
235                Error::InvalidPropertyValue => "Invalid property value",
236                Error::PropertyNotInUse => "Property not in use",
237                Error::Initialized => "Initialized",
238                Error::InvalidOfflineRender => "Invalid offline render",
239                Error::Unauthorized => "Unauthorized",
240                Error::Unknown => "Unknown error occurred",
241            };
242            write!(f, "{}", description)
243        }
244    }
245}
246
247/// A wrapper around all possible Core Audio errors.
248#[derive(Copy, Clone, Debug)]
249pub enum Error {
250    Unspecified,
251    SystemSoundClientMessageTimedOut,
252    NoMatchingDefaultAudioUnitFound,
253    RenderCallbackBufferFormatDoesNotMatchAudioUnitStreamFormat,
254    NoKnownSubtype,
255    NonInterleavedInputOnlySupportsMono,
256    UnsupportedSampleRate,
257    UnsupportedStreamFormat,
258    Audio(AudioError),
259    AudioCodec(AudioCodecError),
260    AudioFormat(AudioFormatError),
261    AudioUnit(AudioUnitError),
262    Unknown(OSStatus),
263}
264
265impl Error {
266    /// Convert an OSStatus to a std Rust Result.
267    pub fn from_os_status(os_status: OSStatus) -> Result<(), Error> {
268        match os_status {
269            0 => Ok(()),
270            -1500 => Err(Error::Unspecified),
271            -1501 => Err(Error::SystemSoundClientMessageTimedOut),
272            _ => {
273                match AudioError::from_os_status(os_status) {
274                    Ok(()) => return Ok(()),
275                    Err(AudioError::Unknown) => (),
276                    Err(err) => return Err(Error::Audio(err)),
277                }
278                match AudioCodecError::from_os_status(os_status) {
279                    Ok(()) => return Ok(()),
280                    Err(AudioCodecError::Unknown) => (),
281                    Err(err) => return Err(Error::AudioCodec(err)),
282                }
283                match AudioFormatError::from_os_status(os_status) {
284                    Ok(()) => return Ok(()),
285                    Err(AudioFormatError::Unknown) => (),
286                    Err(err) => return Err(Error::AudioFormat(err)),
287                }
288                match AudioUnitError::from_os_status(os_status) {
289                    Ok(()) => return Ok(()),
290                    Err(AudioUnitError::Unknown) => (),
291                    Err(err) => return Err(Error::AudioUnit(err)),
292                }
293                Err(Error::Unknown(os_status))
294            }
295        }
296    }
297
298    /// Convert an Error to an OSStatus.
299    pub fn as_os_status(&self) -> OSStatus {
300        match *self {
301            Error::Unspecified => -1500,
302            Error::NoMatchingDefaultAudioUnitFound => -1500,
303            Error::RenderCallbackBufferFormatDoesNotMatchAudioUnitStreamFormat => -1500,
304            Error::SystemSoundClientMessageTimedOut => -1501,
305            Error::Audio(err) => err as OSStatus,
306            Error::AudioCodec(err) => err as OSStatus,
307            Error::AudioUnit(err) => err as OSStatus,
308            _ => -1500,
309        }
310    }
311}
312
313impl std::error::Error for Error {}
314
315impl ::std::fmt::Display for Error {
316    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
317        match *self {
318            Error::Unspecified => write!(f, "An unspecified error has occurred"),
319            Error::NoMatchingDefaultAudioUnitFound => write!(f, "No matching default audio unit found"),
320            Error::RenderCallbackBufferFormatDoesNotMatchAudioUnitStreamFormat =>
321                write!(f, "The given render callback buffer format does not match the `AudioUnit` `StreamFormat`"),
322            Error::SystemSoundClientMessageTimedOut => write!(f, "The system sound client message timed out"),
323            Error::NoKnownSubtype => write!(f, "The type has no known subtypes"),
324            Error::NonInterleavedInputOnlySupportsMono => write!(f, "In non-interleaved mode input only supports one channel"),
325            Error::UnsupportedSampleRate => write!(f, "The requested sample rate is not available"),
326            Error::UnsupportedStreamFormat => write!(f, "The requested stream format is not available"),
327            Error::Audio(ref err) => write!(f, "{}", err),
328            Error::AudioCodec(ref err) => write!(f, "{}", err),
329            Error::AudioFormat(ref err) => write!(f, "{}", err),
330            Error::AudioUnit(ref err) => write!(f, "{}", err),
331            Error::Unknown(_) => write!(f, "An unknown error unknown to the coreaudio-rs API occurred"),
332        }
333    }
334}