fmod/
result.rs

1use fmod_sys::*;
2
3#[cfg(doc)]
4use crate::{OutputType, Sound, System, SystemBuilder, studio};
5
6/// An error that FMOD (or this crate) might return.
7#[derive(Clone, Copy, PartialEq, Eq, Debug)]
8pub enum Error {
9    /// Tried to call a function on a data type that does not allow this type of functionality (ie calling [`Sound::lock`] on a streaming sound).
10    BadCommand,
11    /// Error trying to allocate a channel.
12    ChannelAlloc,
13    /// The specified channel has been reused to play another sound.
14    ChannelStolen,
15    /// DMA Failure.  See debug output for more information.
16    DMA,
17    /// DSP connection error.  Connection possibly caused a cyclic dependency or connected dsps with incompatible buffer counts.
18    DspConnection,
19    /// DSP  code from a DSP process query callback.  Tells mixer not to call the process callback and therefore not consume CPU.  Use this to optimize the DSP graph.
20    DspDontProcess,
21    /// DSP Format error.  A DSP unit may have attempted to connect to this network with the wrong format, or a matrix may have been set with the wrong size if the target unit has a specified channel map.
22    DspFormat,
23    /// DSP is already in the mixer's DSP network. It must be removed before being reinserted or released.
24    DspInuse,
25    /// DSP connection error.  Couldn't find the DSP unit specified.
26    DspNotFound,
27    /// DSP operation error.  Cannot perform operation on this DSP as it is reserved by the system.
28    DspReserved,
29    /// DSP operation error.  Cannot perform operation on this DSP as it is reserved by the system.
30    DspSilence,
31    /// DSP operation cannot be performed on a DSP of this type.
32    DspType,
33    /// Error loading file.
34    FileBad,
35    /// Couldn't perform seek operation.  This is a limitation of the medium (ie netstreams) or the file format.
36    FileCouldNotSeek,
37    /// Media was ejected while reading.
38    FileDiskEjected,
39    /// End of file unexpectedly reached while trying to read essential data (truncated?).
40    FileEof,
41    /// End of current chunk reached while trying to read data.
42    FileEndOfData,
43    /// File not found.
44    FileNotFound,
45    /// Unsupported file or audio format.
46    Format,
47    /// There is a version mismatch between the FMOD header and either the FMOD Studio library or the FMOD Low Level library.
48    HeaderMismatch,
49    /// A HTTP error occurred. This is a catch-all for HTTP errors not listed elsewhere.
50    Http,
51    /// The specified resource requires authentication or is forbidden.
52    HttpAccess,
53    /// Proxy authentication is required to access the specified resource.
54    HttpProxyAuth,
55    /// A HTTP server error occurred.
56    HttpServerError,
57    /// The HTTP request timed out.
58    HttpTimeout,
59    /// FMOD was not initialized correctly to support this function.
60    Initialization,
61    /// Cannot call this command after [`SystemBuilder::build`].
62    Initialized,
63    /// An error occured in the FMOD system. Use the logging version of FMOD for more information.
64    Internal,
65    /// Value passed in was a NaN, Inf or denormalized float.
66    InvalidFloat,
67    /// An invalid object handle was used.
68    InvalidHandle,
69    /// An invalid parameter was passed to this function.
70    InvalidParam,
71    /// An invalid seek position was passed to this function.
72    InvalidPosition,
73    /// An invalid speaker was passed to this function based on the current speaker mode.
74    InvalidSpeaker,
75    /// The syncpoint did not come from this sound handle.
76    InvalidSyncPoint,
77    /// Tried to call a function on a thread that is not supported.
78    InvalidThread,
79    /// The vectors passed in are not unit length, or perpendicular.
80    InvalidVector,
81    /// Reached maximum audible playback count for this sound's soundgroup.
82    MaxAudible,
83    /// Not enough memory or resources.
84    Memory,
85    /// Can't use [`FMOD_OPENMEMORY_POINT`] on non PCM source data, or non mp3/xma/adpcm data if [`FMOD_CREATECOMPRESSEDSAMPLE`] was used.
86    MemoryCantPoint,
87    /// Tried to call a command on a 2d sound when the command was meant for 3d sound.
88    Needs3D,
89    /// Tried to use a feature that requires hardware support.
90    NeedsHardWare,
91    /// Couldn't connect to the specified host.
92    NetConnect,
93    /// A socket error occurred.  This is a catch-all for socket-related errors not listed elsewhere.
94    NetSocketError,
95    /// The specified URL couldn't be resolved.
96    NetUrl,
97    /// The specified URL couldn't be resolved.
98    NetWouldBlock,
99    /// Operation could not be performed because specified sound/DSP connection is not ready.
100    NotReady,
101    /// Error initializing output device, but more specifically, the output device is already in use and cannot be reused.
102    OutputAllocated,
103    /// Error creating hardware sound buffer.
104    OutputCreateBuffer,
105    /// A call to a standard soundcard driver failed, which could possibly mean a bug in the driver or resources were missing or exhausted.
106    OuputDriverCall,
107    /// Soundcard does not support the specified format.
108    OutputFormat,
109    /// Error initializing output device.
110    OutputInit,
111    /// The output device has no drivers installed.  If pre-init, [`OutputType::NoSound`] is selected as the output mode.  If post-init, the function just fails.
112    OutputNoDrivers,
113    /// An unspecified error has been returned from a plugin.
114    Plugin,
115    /// A requested output, dsp unit type or codec was not available.
116    PluginMissing,
117    /// A resource that the plugin requires cannot be allocated or found. (ie the DLS file for MIDI playback)
118    PluginResource,
119    /// A plugin was built with an unsupported SDK version.
120    PluginVersion,
121    /// An error occurred trying to initialize the recording device.
122    Record,
123    /// Reverb properties cannot be set on this channel because a parent channelgroup owns the reverb connection.
124    ReverbChannelGroup,
125    /// Specified instance in [`FMOD_REVERB_PROPERTIES`] couldn't be set. Most likely because it is an invalid instance number or the reverb doesn't exist.
126    ReverbInstance,
127    /// The error occurred because the sound referenced contains subsounds when it shouldn't have, or it doesn't contain subsounds when it should have.  The operation may also not be able to be performed on a parent sound.
128    Subsounds,
129    /// This subsound is already being used by another sound, you cannot have more than one parent to a sound.  Null out the other parent's entry first.
130    SubsoundAllocated,
131    /// Shared subsounds cannot be replaced or moved from their parent stream, such as when the parent stream is an FSB file.
132    SubsoundCantMove,
133    /// The specified tag could not be found or there are no tags.
134    TagNotFound,
135    /// The sound created exceeds the allowable input channel count.
136    /// This can be increased using the 'maxinputchannels' parameter in [`SystemBuilder::software_format`].
137    TooManyChannels,
138    /// The retrieved string is too long to fit in the supplied buffer and has been truncated.
139    Truncated,
140    /// Something in FMOD hasn't been implemented when it should be. Contact support.
141    Unimplemented,
142    /// This command failed because [`SystemBuilder::build`] or [`System::set_driver`] was not called.
143    Uninitialized,
144    /// A command issued was not supported by this object.  Possibly a plugin without certain callbacks specified.
145    Unsupported,
146    /// The version number of this file format is not supported.
147    Version,
148    /// The specified bank has already been loaded.
149    EventAlreadyLoaded,
150    /// The live update connection failed due to the game already being connected.
151    EventLiveUpdateBusy,
152    /// The live update connection failed due to the game data being out of sync with the tool.
153    EventLiveUpdateMismatch,
154    /// The live update connection timed out.
155    EventLiveUpdateTimeout,
156    /// The requested event, parameter, bus or vca could not be found.
157    EventNotFound,
158    /// The [`studio::System`] object is not yet initialized.
159    StudioUninitialized,
160    /// The specified resource is not loaded, so it can't be unloaded.
161    StudioNotLoaded,
162    /// An invalid string was passed to this function.
163    InvalidString,
164    /// The specified resource is already locked.
165    AlreadyLocked,
166    /// The specified resource is not locked, so it can't be unlocked.
167    NotLocked,
168    /// The specified recording driver has been disconnected.
169    RecordDisconnected,
170    /// The length provided exceeds the allowable limit.
171    TooManySamples,
172
173    /// Failed to turn a number into an enum value
174    ///
175    /// This error does not come from FMOD, and instead comes from this crate.
176    /// If this error is ever returned from this crate, please file an issue!
177    EnumFromPrivitive {
178        /// The enum name
179        name: &'static str,
180        /// The invalid number
181        primitive: i64,
182    },
183}
184
185impl std::fmt::Display for Error {
186    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
187        match self {
188            Error::EnumFromPrivitive { name, primitive } => f.write_fmt(format_args!(
189                "No discriminant in enum `{name}` matches the value `{primitive:?}. If you got this error from an FMOD function, please file an issue!"
190            )),
191            error => {
192                let fmod_result = (*error).into();
193                f.write_str(fmod_sys::error_code_to_str(fmod_result))
194            }
195        }
196    }
197}
198
199impl std::error::Error for Error {}
200
201/// Shorthand for [`std::result::Result<T, Error>`]
202pub type Result<T> = std::result::Result<T, Error>;
203
204impl From<FMOD_RESULT> for Error {
205    fn from(value: FMOD_RESULT) -> Self {
206        match value {
207            FMOD_RESULT::FMOD_ERR_BADCOMMAND => Error::BadCommand,
208            FMOD_RESULT::FMOD_ERR_CHANNEL_ALLOC => Error::ChannelAlloc,
209            FMOD_RESULT::FMOD_ERR_CHANNEL_STOLEN => Error::ChannelStolen,
210            FMOD_RESULT::FMOD_ERR_DMA => Error::DMA,
211            FMOD_RESULT::FMOD_ERR_DSP_CONNECTION => Error::DspConnection,
212            FMOD_RESULT::FMOD_ERR_DSP_DONTPROCESS => Error::DspDontProcess,
213            FMOD_RESULT::FMOD_ERR_DSP_FORMAT => Error::DspFormat,
214            FMOD_RESULT::FMOD_ERR_DSP_INUSE => Error::DspInuse,
215            FMOD_RESULT::FMOD_ERR_DSP_NOTFOUND => Error::DspNotFound,
216            FMOD_RESULT::FMOD_ERR_DSP_RESERVED => Error::DspReserved,
217            FMOD_RESULT::FMOD_ERR_DSP_SILENCE => Error::DspSilence,
218            FMOD_RESULT::FMOD_ERR_DSP_TYPE => Error::DspType,
219            FMOD_RESULT::FMOD_ERR_FILE_BAD => Error::FileBad,
220            FMOD_RESULT::FMOD_ERR_FILE_COULDNOTSEEK => Error::FileCouldNotSeek,
221            FMOD_RESULT::FMOD_ERR_FILE_DISKEJECTED => Error::FileDiskEjected,
222            FMOD_RESULT::FMOD_ERR_FILE_EOF => Error::FileEof,
223            FMOD_RESULT::FMOD_ERR_FILE_ENDOFDATA => Error::FileEndOfData,
224            FMOD_RESULT::FMOD_ERR_FILE_NOTFOUND => Error::FileNotFound,
225            FMOD_RESULT::FMOD_ERR_FORMAT => Error::Format,
226            FMOD_RESULT::FMOD_ERR_HEADER_MISMATCH => Error::HeaderMismatch,
227            FMOD_RESULT::FMOD_ERR_HTTP => Error::Http,
228            FMOD_RESULT::FMOD_ERR_HTTP_ACCESS => Error::HttpAccess,
229            FMOD_RESULT::FMOD_ERR_HTTP_PROXY_AUTH => Error::HttpProxyAuth,
230            FMOD_RESULT::FMOD_ERR_HTTP_SERVER_ERROR => Error::HttpServerError,
231            FMOD_RESULT::FMOD_ERR_HTTP_TIMEOUT => Error::HttpTimeout,
232            FMOD_RESULT::FMOD_ERR_INITIALIZATION => Error::Initialization,
233            FMOD_RESULT::FMOD_ERR_INITIALIZED => Error::Initialized,
234            FMOD_RESULT::FMOD_ERR_INTERNAL => Error::Internal,
235            FMOD_RESULT::FMOD_ERR_INVALID_FLOAT => Error::InvalidFloat,
236            FMOD_RESULT::FMOD_ERR_INVALID_HANDLE => Error::InvalidHandle,
237            FMOD_RESULT::FMOD_ERR_INVALID_PARAM => Error::InvalidParam,
238            FMOD_RESULT::FMOD_ERR_INVALID_POSITION => Error::InvalidPosition,
239            FMOD_RESULT::FMOD_ERR_INVALID_SPEAKER => Error::InvalidSpeaker,
240            FMOD_RESULT::FMOD_ERR_INVALID_SYNCPOINT => Error::InvalidSyncPoint,
241            FMOD_RESULT::FMOD_ERR_INVALID_THREAD => Error::InvalidThread,
242            FMOD_RESULT::FMOD_ERR_INVALID_VECTOR => Error::InvalidVector,
243            FMOD_RESULT::FMOD_ERR_MAXAUDIBLE => Error::MaxAudible,
244            FMOD_RESULT::FMOD_ERR_MEMORY => Error::Memory,
245            FMOD_RESULT::FMOD_ERR_MEMORY_CANTPOINT => Error::MemoryCantPoint,
246            FMOD_RESULT::FMOD_ERR_NEEDS3D => Error::Needs3D,
247            FMOD_RESULT::FMOD_ERR_NEEDSHARDWARE => Error::NeedsHardWare,
248            FMOD_RESULT::FMOD_ERR_NET_CONNECT => Error::NetConnect,
249            FMOD_RESULT::FMOD_ERR_NET_SOCKET_ERROR => Error::NetSocketError,
250            FMOD_RESULT::FMOD_ERR_NET_URL => Error::NetUrl,
251            FMOD_RESULT::FMOD_ERR_NET_WOULD_BLOCK => Error::NetWouldBlock,
252            FMOD_RESULT::FMOD_ERR_NOTREADY => Error::NotReady,
253            FMOD_RESULT::FMOD_ERR_OUTPUT_ALLOCATED => Error::OutputAllocated,
254            FMOD_RESULT::FMOD_ERR_OUTPUT_CREATEBUFFER => Error::OutputCreateBuffer,
255            FMOD_RESULT::FMOD_ERR_OUTPUT_DRIVERCALL => Error::OuputDriverCall,
256            FMOD_RESULT::FMOD_ERR_OUTPUT_FORMAT => Error::OutputFormat,
257            FMOD_RESULT::FMOD_ERR_OUTPUT_INIT => Error::OutputInit,
258            FMOD_RESULT::FMOD_ERR_OUTPUT_NODRIVERS => Error::OutputNoDrivers,
259            FMOD_RESULT::FMOD_ERR_PLUGIN => Error::Plugin,
260            FMOD_RESULT::FMOD_ERR_PLUGIN_MISSING => Error::PluginMissing,
261            FMOD_RESULT::FMOD_ERR_PLUGIN_RESOURCE => Error::PluginResource,
262            FMOD_RESULT::FMOD_ERR_PLUGIN_VERSION => Error::PluginVersion,
263            FMOD_RESULT::FMOD_ERR_RECORD => Error::Record,
264            FMOD_RESULT::FMOD_ERR_REVERB_CHANNELGROUP => Error::ReverbChannelGroup,
265            FMOD_RESULT::FMOD_ERR_REVERB_INSTANCE => Error::ReverbInstance,
266            FMOD_RESULT::FMOD_ERR_SUBSOUNDS => Error::Subsounds,
267            FMOD_RESULT::FMOD_ERR_SUBSOUND_ALLOCATED => Error::SubsoundAllocated,
268            FMOD_RESULT::FMOD_ERR_SUBSOUND_CANTMOVE => Error::SubsoundCantMove,
269            FMOD_RESULT::FMOD_ERR_TAGNOTFOUND => Error::TagNotFound,
270            FMOD_RESULT::FMOD_ERR_TOOMANYCHANNELS => Error::TooManyChannels,
271            FMOD_RESULT::FMOD_ERR_TRUNCATED => Error::Truncated,
272            FMOD_RESULT::FMOD_ERR_UNIMPLEMENTED => Error::Unimplemented,
273            FMOD_RESULT::FMOD_ERR_UNINITIALIZED => Error::Uninitialized,
274            FMOD_RESULT::FMOD_ERR_UNSUPPORTED => Error::Unsupported,
275            FMOD_RESULT::FMOD_ERR_VERSION => Error::Version,
276            FMOD_RESULT::FMOD_ERR_EVENT_ALREADY_LOADED => Error::EventAlreadyLoaded,
277            FMOD_RESULT::FMOD_ERR_EVENT_LIVEUPDATE_BUSY => Error::EventLiveUpdateBusy,
278            FMOD_RESULT::FMOD_ERR_EVENT_LIVEUPDATE_MISMATCH => Error::EventLiveUpdateMismatch,
279            FMOD_RESULT::FMOD_ERR_EVENT_LIVEUPDATE_TIMEOUT => Error::EventLiveUpdateTimeout,
280            FMOD_RESULT::FMOD_ERR_EVENT_NOTFOUND => Error::EventNotFound,
281            FMOD_RESULT::FMOD_ERR_STUDIO_UNINITIALIZED => Error::StudioUninitialized,
282            FMOD_RESULT::FMOD_ERR_STUDIO_NOT_LOADED => Error::StudioNotLoaded,
283            FMOD_RESULT::FMOD_ERR_INVALID_STRING => Error::InvalidString,
284            FMOD_RESULT::FMOD_ERR_ALREADY_LOCKED => Error::AlreadyLocked,
285            FMOD_RESULT::FMOD_ERR_NOT_LOCKED => Error::NotLocked,
286            FMOD_RESULT::FMOD_ERR_RECORD_DISCONNECTED => Error::RecordDisconnected,
287            FMOD_RESULT::FMOD_ERR_TOOMANYSAMPLES => Error::TooManySamples,
288            _ => panic!("invalid value"),
289        }
290    }
291}
292
293impl<T> From<num_enum::TryFromPrimitiveError<T>> for Error
294where
295    T: num_enum::TryFromPrimitive,
296    T::Primitive: Into<i64>,
297{
298    fn from(value: num_enum::TryFromPrimitiveError<T>) -> Self {
299        Self::EnumFromPrivitive {
300            name: T::NAME,
301            primitive: value.number.into(),
302        }
303    }
304}
305
306#[allow(clippy::match_same_arms)]
307impl From<Error> for FMOD_RESULT {
308    fn from(val: Error) -> Self {
309        match val {
310            Error::BadCommand => FMOD_RESULT::FMOD_ERR_BADCOMMAND,
311            Error::ChannelAlloc => FMOD_RESULT::FMOD_ERR_CHANNEL_ALLOC,
312            Error::ChannelStolen => FMOD_RESULT::FMOD_ERR_CHANNEL_STOLEN,
313            Error::DMA => FMOD_RESULT::FMOD_ERR_DMA,
314            Error::DspConnection => FMOD_RESULT::FMOD_ERR_DSP_CONNECTION,
315            Error::DspDontProcess => FMOD_RESULT::FMOD_ERR_DSP_DONTPROCESS,
316            Error::DspFormat => FMOD_RESULT::FMOD_ERR_DSP_FORMAT,
317            Error::DspInuse => FMOD_RESULT::FMOD_ERR_DSP_INUSE,
318            Error::DspNotFound => FMOD_RESULT::FMOD_ERR_DSP_NOTFOUND,
319            Error::DspReserved => FMOD_RESULT::FMOD_ERR_DSP_RESERVED,
320            Error::DspSilence => FMOD_RESULT::FMOD_ERR_DSP_SILENCE,
321            Error::DspType => FMOD_RESULT::FMOD_ERR_DSP_TYPE,
322            Error::FileBad => FMOD_RESULT::FMOD_ERR_FILE_BAD,
323            Error::FileCouldNotSeek => FMOD_RESULT::FMOD_ERR_FILE_COULDNOTSEEK,
324            Error::FileDiskEjected => FMOD_RESULT::FMOD_ERR_FILE_DISKEJECTED,
325            Error::FileEof => FMOD_RESULT::FMOD_ERR_FILE_EOF,
326            Error::FileEndOfData => FMOD_RESULT::FMOD_ERR_FILE_ENDOFDATA,
327            Error::FileNotFound => FMOD_RESULT::FMOD_ERR_FILE_NOTFOUND,
328            Error::Format => FMOD_RESULT::FMOD_ERR_FORMAT,
329            Error::HeaderMismatch => FMOD_RESULT::FMOD_ERR_HEADER_MISMATCH,
330            Error::Http => FMOD_RESULT::FMOD_ERR_HTTP,
331            Error::HttpAccess => FMOD_RESULT::FMOD_ERR_HTTP_ACCESS,
332            Error::HttpProxyAuth => FMOD_RESULT::FMOD_ERR_HTTP_PROXY_AUTH,
333            Error::HttpServerError => FMOD_RESULT::FMOD_ERR_HTTP_SERVER_ERROR,
334            Error::HttpTimeout => FMOD_RESULT::FMOD_ERR_HTTP_TIMEOUT,
335            Error::Initialization => FMOD_RESULT::FMOD_ERR_INITIALIZATION,
336            Error::Initialized => FMOD_RESULT::FMOD_ERR_INITIALIZED,
337            Error::Internal => FMOD_RESULT::FMOD_ERR_INTERNAL,
338            Error::InvalidFloat => FMOD_RESULT::FMOD_ERR_INVALID_FLOAT,
339            Error::InvalidHandle => FMOD_RESULT::FMOD_ERR_INVALID_HANDLE,
340            Error::InvalidParam => FMOD_RESULT::FMOD_ERR_INVALID_PARAM,
341            Error::InvalidPosition => FMOD_RESULT::FMOD_ERR_INVALID_POSITION,
342            Error::InvalidSpeaker => FMOD_RESULT::FMOD_ERR_INVALID_SPEAKER,
343            Error::InvalidSyncPoint => FMOD_RESULT::FMOD_ERR_INVALID_SYNCPOINT,
344            Error::InvalidThread => FMOD_RESULT::FMOD_ERR_INVALID_THREAD,
345            Error::InvalidVector => FMOD_RESULT::FMOD_ERR_INVALID_VECTOR,
346            Error::MaxAudible => FMOD_RESULT::FMOD_ERR_MAXAUDIBLE,
347            Error::Memory => FMOD_RESULT::FMOD_ERR_MEMORY,
348            Error::MemoryCantPoint => FMOD_RESULT::FMOD_ERR_MEMORY_CANTPOINT,
349            Error::Needs3D => FMOD_RESULT::FMOD_ERR_NEEDS3D,
350            Error::NeedsHardWare => FMOD_RESULT::FMOD_ERR_NEEDSHARDWARE,
351            Error::NetConnect => FMOD_RESULT::FMOD_ERR_NET_CONNECT,
352            Error::NetSocketError => FMOD_RESULT::FMOD_ERR_NET_SOCKET_ERROR,
353            Error::NetUrl => FMOD_RESULT::FMOD_ERR_NET_URL,
354            Error::NetWouldBlock => FMOD_RESULT::FMOD_ERR_NET_WOULD_BLOCK,
355            Error::NotReady => FMOD_RESULT::FMOD_ERR_NOTREADY,
356            Error::OutputAllocated => FMOD_RESULT::FMOD_ERR_OUTPUT_ALLOCATED,
357            Error::OutputCreateBuffer => FMOD_RESULT::FMOD_ERR_OUTPUT_CREATEBUFFER,
358            Error::OuputDriverCall => FMOD_RESULT::FMOD_ERR_OUTPUT_DRIVERCALL,
359            Error::OutputFormat => FMOD_RESULT::FMOD_ERR_OUTPUT_FORMAT,
360            Error::OutputInit => FMOD_RESULT::FMOD_ERR_OUTPUT_INIT,
361            Error::OutputNoDrivers => FMOD_RESULT::FMOD_ERR_OUTPUT_NODRIVERS,
362            Error::Plugin => FMOD_RESULT::FMOD_ERR_PLUGIN,
363            Error::PluginMissing => FMOD_RESULT::FMOD_ERR_PLUGIN_MISSING,
364            Error::PluginResource => FMOD_RESULT::FMOD_ERR_PLUGIN_RESOURCE,
365            Error::PluginVersion => FMOD_RESULT::FMOD_ERR_PLUGIN_VERSION,
366            Error::Record => FMOD_RESULT::FMOD_ERR_RECORD,
367            Error::ReverbChannelGroup => FMOD_RESULT::FMOD_ERR_REVERB_CHANNELGROUP,
368            Error::ReverbInstance => FMOD_RESULT::FMOD_ERR_REVERB_INSTANCE,
369            Error::Subsounds => FMOD_RESULT::FMOD_ERR_SUBSOUNDS,
370            Error::SubsoundAllocated => FMOD_RESULT::FMOD_ERR_SUBSOUND_ALLOCATED,
371            Error::SubsoundCantMove => FMOD_RESULT::FMOD_ERR_SUBSOUND_CANTMOVE,
372            Error::TagNotFound => FMOD_RESULT::FMOD_ERR_TAGNOTFOUND,
373            Error::TooManyChannels => FMOD_RESULT::FMOD_ERR_TOOMANYCHANNELS,
374            Error::Truncated => FMOD_RESULT::FMOD_ERR_TRUNCATED,
375            Error::Unimplemented => FMOD_RESULT::FMOD_ERR_UNIMPLEMENTED,
376            Error::Uninitialized => FMOD_RESULT::FMOD_ERR_UNINITIALIZED,
377            Error::Unsupported => FMOD_RESULT::FMOD_ERR_UNSUPPORTED,
378            Error::Version => FMOD_RESULT::FMOD_ERR_VERSION,
379            Error::EventAlreadyLoaded => FMOD_RESULT::FMOD_ERR_EVENT_ALREADY_LOADED,
380            Error::EventLiveUpdateBusy => FMOD_RESULT::FMOD_ERR_EVENT_LIVEUPDATE_BUSY,
381            Error::EventLiveUpdateMismatch => FMOD_RESULT::FMOD_ERR_EVENT_LIVEUPDATE_MISMATCH,
382            Error::EventLiveUpdateTimeout => FMOD_RESULT::FMOD_ERR_EVENT_LIVEUPDATE_TIMEOUT,
383            Error::EventNotFound => FMOD_RESULT::FMOD_ERR_EVENT_NOTFOUND,
384            Error::StudioUninitialized => FMOD_RESULT::FMOD_ERR_STUDIO_UNINITIALIZED,
385            Error::StudioNotLoaded => FMOD_RESULT::FMOD_ERR_STUDIO_NOT_LOADED,
386            Error::InvalidString => FMOD_RESULT::FMOD_ERR_INVALID_STRING,
387            Error::AlreadyLocked => FMOD_RESULT::FMOD_ERR_ALREADY_LOCKED,
388            Error::NotLocked => FMOD_RESULT::FMOD_ERR_NOT_LOCKED,
389            Error::RecordDisconnected => FMOD_RESULT::FMOD_ERR_RECORD_DISCONNECTED,
390            Error::TooManySamples => FMOD_RESULT::FMOD_ERR_TOOMANYSAMPLES,
391            // we want this logically separated
392            Error::EnumFromPrivitive { .. } => FMOD_RESULT::FMOD_ERR_INVALID_PARAM,
393        }
394    }
395}
396
397pub(crate) trait FmodResultExt {
398    fn to_result(self) -> Result<()>;
399
400    fn to_error(self) -> Option<Error>;
401
402    fn from_result<T>(result: Result<T>) -> Self;
403}
404
405impl FmodResultExt for FMOD_RESULT {
406    fn to_result(self) -> Result<()> {
407        if matches!(self, FMOD_RESULT::FMOD_OK) {
408            Ok(())
409        } else {
410            Err(self.into())
411        }
412    }
413
414    fn to_error(self) -> Option<Error> {
415        self.to_result().err()
416    }
417
418    fn from_result<T>(result: Result<T>) -> Self {
419        match result {
420            Ok(_) => FMOD_RESULT::FMOD_OK,
421            Err(e) => e.into(),
422        }
423    }
424}