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