1 | use std::error::Error; |
2 | use std::fmt::{Display, Formatter}; |
3 | |
4 | /// The requested host, although supported on this platform, is unavailable. |
5 | #[derive (Copy, Clone, Debug)] |
6 | pub struct HostUnavailable; |
7 | |
8 | impl Display for HostUnavailable { |
9 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |
10 | f.write_str(data:"the requested host is unavailable" ) |
11 | } |
12 | } |
13 | |
14 | impl Error for HostUnavailable {} |
15 | |
16 | /// Some error has occurred that is specific to the backend from which it was produced. |
17 | /// |
18 | /// This error is often used as a catch-all in cases where: |
19 | /// |
20 | /// - It is unclear exactly what error might be produced by the backend API. |
21 | /// - It does not make sense to add a variant to the enclosing error type. |
22 | /// - No error was expected to occur at all, but we return an error to avoid the possibility of a |
23 | /// `panic!` caused by some unforeseen or unknown reason. |
24 | /// |
25 | /// **Note:** If you notice a `BackendSpecificError` that you believe could be better handled in a |
26 | /// cross-platform manner, please create an issue or submit a pull request with a patch that adds |
27 | /// the necessary error variant to the appropriate error enum. |
28 | #[derive (Clone, Debug)] |
29 | pub struct BackendSpecificError { |
30 | pub description: String, |
31 | } |
32 | |
33 | impl Display for BackendSpecificError { |
34 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |
35 | write!( |
36 | f, |
37 | "A backend-specific error has occurred: {}" , |
38 | self.description |
39 | ) |
40 | } |
41 | } |
42 | |
43 | impl Error for BackendSpecificError {} |
44 | |
45 | /// An error that might occur while attempting to enumerate the available devices on a system. |
46 | #[derive (Clone, Debug)] |
47 | pub enum DevicesError { |
48 | /// See the [`BackendSpecificError`] docs for more information about this error variant. |
49 | BackendSpecific { err: BackendSpecificError }, |
50 | } |
51 | |
52 | impl Display for DevicesError { |
53 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |
54 | match self { |
55 | Self::BackendSpecific { err: &BackendSpecificError } => err.fmt(f), |
56 | } |
57 | } |
58 | } |
59 | |
60 | impl Error for DevicesError {} |
61 | |
62 | impl From<BackendSpecificError> for DevicesError { |
63 | fn from(err: BackendSpecificError) -> Self { |
64 | Self::BackendSpecific { err } |
65 | } |
66 | } |
67 | |
68 | /// An error that may occur while attempting to retrieve a device name. |
69 | #[derive (Clone, Debug)] |
70 | pub enum DeviceNameError { |
71 | /// See the [`BackendSpecificError`] docs for more information about this error variant. |
72 | BackendSpecific { err: BackendSpecificError }, |
73 | } |
74 | |
75 | impl Display for DeviceNameError { |
76 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |
77 | match self { |
78 | Self::BackendSpecific { err: &BackendSpecificError } => err.fmt(f), |
79 | } |
80 | } |
81 | } |
82 | |
83 | impl Error for DeviceNameError {} |
84 | |
85 | impl From<BackendSpecificError> for DeviceNameError { |
86 | fn from(err: BackendSpecificError) -> Self { |
87 | Self::BackendSpecific { err } |
88 | } |
89 | } |
90 | |
91 | /// Error that can happen when enumerating the list of supported formats. |
92 | #[derive (Debug)] |
93 | pub enum SupportedStreamConfigsError { |
94 | /// The device no longer exists. This can happen if the device is disconnected while the |
95 | /// program is running. |
96 | DeviceNotAvailable, |
97 | /// We called something the C-Layer did not understand |
98 | InvalidArgument, |
99 | /// See the [`BackendSpecificError`] docs for more information about this error variant. |
100 | BackendSpecific { err: BackendSpecificError }, |
101 | } |
102 | |
103 | impl Display for SupportedStreamConfigsError { |
104 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |
105 | match self { |
106 | Self::BackendSpecific { err: &BackendSpecificError } => err.fmt(f), |
107 | Self::DeviceNotAvailable => f.write_str(data:"The requested device is no longer available. For example, it has been unplugged." ), |
108 | Self::InvalidArgument => f.write_str(data:"Invalid argument passed to the backend. For example, this happens when trying to read capture capabilities when the device does not support it." ) |
109 | } |
110 | } |
111 | } |
112 | |
113 | impl Error for SupportedStreamConfigsError {} |
114 | |
115 | impl From<BackendSpecificError> for SupportedStreamConfigsError { |
116 | fn from(err: BackendSpecificError) -> Self { |
117 | Self::BackendSpecific { err } |
118 | } |
119 | } |
120 | |
121 | /// May occur when attempting to request the default input or output stream format from a [`Device`](crate::Device). |
122 | #[derive (Debug)] |
123 | pub enum DefaultStreamConfigError { |
124 | /// The device no longer exists. This can happen if the device is disconnected while the |
125 | /// program is running. |
126 | DeviceNotAvailable, |
127 | /// Returned if e.g. the default input format was requested on an output-only audio device. |
128 | StreamTypeNotSupported, |
129 | /// See the [`BackendSpecificError`] docs for more information about this error variant. |
130 | BackendSpecific { err: BackendSpecificError }, |
131 | } |
132 | |
133 | impl Display for DefaultStreamConfigError { |
134 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |
135 | match self { |
136 | Self::BackendSpecific { err: &BackendSpecificError } => err.fmt(f), |
137 | DefaultStreamConfigError::DeviceNotAvailable => f.write_str( |
138 | data:"The requested device is no longer available. For example, it has been unplugged." , |
139 | ), |
140 | DefaultStreamConfigError::StreamTypeNotSupported => { |
141 | f.write_str(data:"The requested stream type is not supported by the device." ) |
142 | } |
143 | } |
144 | } |
145 | } |
146 | |
147 | impl Error for DefaultStreamConfigError {} |
148 | |
149 | impl From<BackendSpecificError> for DefaultStreamConfigError { |
150 | fn from(err: BackendSpecificError) -> Self { |
151 | Self::BackendSpecific { err } |
152 | } |
153 | } |
154 | /// Error that can happen when creating a [`Stream`](crate::Stream). |
155 | #[derive (Debug)] |
156 | pub enum BuildStreamError { |
157 | /// The device no longer exists. This can happen if the device is disconnected while the |
158 | /// program is running. |
159 | DeviceNotAvailable, |
160 | /// The specified stream configuration is not supported. |
161 | StreamConfigNotSupported, |
162 | /// We called something the C-Layer did not understand |
163 | /// |
164 | /// On ALSA device functions called with a feature they do not support will yield this. E.g. |
165 | /// Trying to use capture capabilities on an output only format yields this. |
166 | InvalidArgument, |
167 | /// Occurs if adding a new Stream ID would cause an integer overflow. |
168 | StreamIdOverflow, |
169 | /// See the [`BackendSpecificError`] docs for more information about this error variant. |
170 | BackendSpecific { err: BackendSpecificError }, |
171 | } |
172 | |
173 | impl Display for BuildStreamError { |
174 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |
175 | match self { |
176 | Self::BackendSpecific { err: &BackendSpecificError } => err.fmt(f), |
177 | BuildStreamError::DeviceNotAvailable => f.write_str( |
178 | data:"The requested device is no longer available. For example, it has been unplugged." , |
179 | ), |
180 | BuildStreamError::StreamConfigNotSupported => { |
181 | f.write_str(data:"The requested stream configuration is not supported by the device." ) |
182 | } |
183 | BuildStreamError::InvalidArgument => f.write_str( |
184 | data:"The requested device does not support this capability (invalid argument)" , |
185 | ), |
186 | BuildStreamError::StreamIdOverflow => { |
187 | f.write_str(data:"Adding a new stream ID would cause an overflow" ) |
188 | } |
189 | } |
190 | } |
191 | } |
192 | |
193 | impl Error for BuildStreamError {} |
194 | |
195 | impl From<BackendSpecificError> for BuildStreamError { |
196 | fn from(err: BackendSpecificError) -> Self { |
197 | Self::BackendSpecific { err } |
198 | } |
199 | } |
200 | |
201 | /// Errors that might occur when calling [`Stream::play()`](crate::traits::StreamTrait::play). |
202 | /// |
203 | /// As of writing this, only macOS may immediately return an error while calling this method. This |
204 | /// is because both the alsa and wasapi backends only enqueue these commands and do not process |
205 | /// them immediately. |
206 | #[derive (Debug)] |
207 | pub enum PlayStreamError { |
208 | /// The device associated with the stream is no longer available. |
209 | DeviceNotAvailable, |
210 | /// See the [`BackendSpecificError`] docs for more information about this error variant. |
211 | BackendSpecific { err: BackendSpecificError }, |
212 | } |
213 | |
214 | impl Display for PlayStreamError { |
215 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |
216 | match self { |
217 | Self::BackendSpecific { err: &BackendSpecificError } => err.fmt(f), |
218 | PlayStreamError::DeviceNotAvailable => { |
219 | f.write_str(data:"the device associated with the stream is no longer available" ) |
220 | } |
221 | } |
222 | } |
223 | } |
224 | |
225 | impl Error for PlayStreamError {} |
226 | |
227 | impl From<BackendSpecificError> for PlayStreamError { |
228 | fn from(err: BackendSpecificError) -> Self { |
229 | Self::BackendSpecific { err } |
230 | } |
231 | } |
232 | |
233 | /// Errors that might occur when calling [`Stream::pause()`](crate::traits::StreamTrait::pause). |
234 | /// |
235 | /// As of writing this, only macOS may immediately return an error while calling this method. This |
236 | /// is because both the alsa and wasapi backends only enqueue these commands and do not process |
237 | /// them immediately. |
238 | #[derive (Debug)] |
239 | pub enum PauseStreamError { |
240 | /// The device associated with the stream is no longer available. |
241 | DeviceNotAvailable, |
242 | /// See the [`BackendSpecificError`] docs for more information about this error variant. |
243 | BackendSpecific { err: BackendSpecificError }, |
244 | } |
245 | |
246 | impl Display for PauseStreamError { |
247 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |
248 | match self { |
249 | Self::BackendSpecific { err: &BackendSpecificError } => err.fmt(f), |
250 | PauseStreamError::DeviceNotAvailable => { |
251 | f.write_str(data:"the device associated with the stream is no longer available" ) |
252 | } |
253 | } |
254 | } |
255 | } |
256 | |
257 | impl Error for PauseStreamError {} |
258 | |
259 | impl From<BackendSpecificError> for PauseStreamError { |
260 | fn from(err: BackendSpecificError) -> Self { |
261 | Self::BackendSpecific { err } |
262 | } |
263 | } |
264 | |
265 | /// Errors that might occur while a stream is running. |
266 | #[derive (Debug)] |
267 | pub enum StreamError { |
268 | /// The device no longer exists. This can happen if the device is disconnected while the |
269 | /// program is running. |
270 | DeviceNotAvailable, |
271 | /// See the [`BackendSpecificError`] docs for more information about this error variant. |
272 | BackendSpecific { err: BackendSpecificError }, |
273 | } |
274 | |
275 | impl Display for StreamError { |
276 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |
277 | match self { |
278 | Self::BackendSpecific { err: &BackendSpecificError } => err.fmt(f), |
279 | StreamError::DeviceNotAvailable => f.write_str( |
280 | data:"The requested device is no longer available. For example, it has been unplugged." , |
281 | ), |
282 | } |
283 | } |
284 | } |
285 | |
286 | impl Error for StreamError {} |
287 | |
288 | impl From<BackendSpecificError> for StreamError { |
289 | fn from(err: BackendSpecificError) -> Self { |
290 | Self::BackendSpecific { err } |
291 | } |
292 | } |
293 | |