From bd806ef45054858118676d66d0954d4579f6ac03 Mon Sep 17 00:00:00 2001 From: Marco Farruggio Date: Mon, 14 Sep 2026 13:43:31 +0100 Subject: [PATCH 01/11] only add null host if there's no custom host --- src/platform/mod.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/platform/mod.rs b/src/platform/mod.rs index 5b2d5aeb6..fc859a267 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -1012,11 +1012,20 @@ mod platform_impl { use crate::host::null::Host as NullHost; impl_platform_host!( - Null => NullHost, - #[cfg(feature = "custom")] Custom => super::CustomHost, + #[cfg(not(feature = "custom"))] Null => NullHost, + #[cfg(feature = "custom")] Custom => CustomHost, ); /// The default host for the current compilation target platform. + #[cfg(feature = "custom")] + pub fn default_host() -> Host { + CustomHost::new() + .expect("the default host should always be available") + .into() + } + + /// The default host for the current compilation target platform. + #[cfg(not(feature = "custom"))] pub fn default_host() -> Host { NullHost::new() .expect("the default host should always be available") From d489cb20fb0cee1d0e36c6a00a9bd1d77db85c12 Mon Sep 17 00:00:00 2001 From: Marco Farruggio Date: Mon, 14 Sep 2026 13:44:16 +0100 Subject: [PATCH 02/11] made new() part of the HostTrait --- src/host/aaudio/mod.rs | 10 ++++------ src/host/alsa/mod.rs | 24 ++++++++++++------------ src/host/asio/mod.rs | 12 +++++------- src/host/audioworklet/mod.rs | 12 +++++------- src/host/coreaudio/ios/mod.rs | 10 ++++------ src/host/coreaudio/macos/mod.rs | 10 ++++------ src/host/custom/mod.rs | 9 ++++----- src/host/jack/mod.rs | 23 ++++++++++++----------- src/host/null/mod.rs | 11 ++++------- src/host/pipewire/mod.rs | 26 +++++++++++++------------- src/host/pulseaudio/mod.rs | 12 +++++------- src/host/wasapi/mod.rs | 10 ++++------ src/host/webaudio/mod.rs | 12 +++++------- src/platform/mod.rs | 19 +++++++++++++++++++ src/traits.rs | 4 ++++ 15 files changed, 104 insertions(+), 100 deletions(-) diff --git a/src/host/aaudio/mod.rs b/src/host/aaudio/mod.rs index 2de6551bb..a54f57a48 100644 --- a/src/host/aaudio/mod.rs +++ b/src/host/aaudio/mod.rs @@ -158,16 +158,14 @@ struct BufferTuningState { pub use crate::iter::{SupportedInputConfigs, SupportedOutputConfigs}; pub type Devices = std::vec::IntoIter; -impl Host { - pub fn new() -> Result { - Ok(Host) - } -} - impl HostTrait for Host { type Devices = Devices; type Device = Device; + fn new() -> Result { + Ok(Host) + } + fn is_available() -> bool { true } diff --git a/src/host/alsa/mod.rs b/src/host/alsa/mod.rs index 076306d29..d4f04826f 100644 --- a/src/host/alsa/mod.rs +++ b/src/host/alsa/mod.rs @@ -127,18 +127,6 @@ pub struct Host { } impl Host { - pub fn new() -> Result { - let inner = AlsaContext::new().map_err(|e| { - Error::with_message( - ErrorKind::HostUnavailable, - format!("ALSA is not available: {e}"), - ) - })?; - Ok(Self { - inner: Arc::new(inner), - }) - } - // "default" is a virtual ALSA device that redirects to the configured default. We cannot // determine its actual capabilities without opening it, so we return Unknown direction. fn default_device(&self) -> Device { @@ -155,6 +143,18 @@ impl HostTrait for Host { type Devices = Devices; type Device = Device; + fn new() -> Result { + let inner = AlsaContext::new().map_err(|e| { + Error::with_message( + ErrorKind::HostUnavailable, + format!("ALSA is not available: {e}"), + ) + })?; + Ok(Self { + inner: Arc::new(inner), + }) + } + fn is_available() -> bool { // Assume ALSA is always available on Linux and BSD. true diff --git a/src/host/asio/mod.rs b/src/host/asio/mod.rs index 3d91a1818..882b800ff 100644 --- a/src/host/asio/mod.rs +++ b/src/host/asio/mod.rs @@ -36,8 +36,11 @@ pub struct Host { asio: Arc, } -impl Host { - pub fn new() -> Result { +impl HostTrait for Host { + type Devices = Devices; + type Device = Device; + + fn new() -> Result { com::com_initialized(); let asio = GLOBAL_ASIO .get_or_init(|| Arc::new(sys::Asio::new())) @@ -45,11 +48,6 @@ impl Host { let host = Host { asio }; Ok(host) } -} - -impl HostTrait for Host { - type Devices = Devices; - type Device = Device; fn is_available() -> bool { true diff --git a/src/host/audioworklet/mod.rs b/src/host/audioworklet/mod.rs index b25503580..383a2ae82 100644 --- a/src/host/audioworklet/mod.rs +++ b/src/host/audioworklet/mod.rs @@ -203,8 +203,11 @@ enum Command { Pause, } -impl Host { - pub fn new() -> Result { +impl HostTrait for Host { + type Devices = Devices; + type Device = Device; + + fn new() -> Result { if Self::is_available() { Ok(Host) } else { @@ -214,11 +217,6 @@ impl Host { )) } } -} - -impl HostTrait for Host { - type Devices = Devices; - type Device = Device; fn is_available() -> bool { if let Some(window) = web_sys::window() { diff --git a/src/host/coreaudio/ios/mod.rs b/src/host/coreaudio/ios/mod.rs index 9a1eaf898..d664b095f 100644 --- a/src/host/coreaudio/ios/mod.rs +++ b/src/host/coreaudio/ios/mod.rs @@ -54,16 +54,14 @@ impl fmt::Display for Device { pub struct Host; -impl Host { - pub fn new() -> Result { - Ok(Host) - } -} - impl HostTrait for Host { type Devices = Devices; type Device = Device; + fn new() -> Result { + Ok(Host) + } + fn is_available() -> bool { true } diff --git a/src/host/coreaudio/macos/mod.rs b/src/host/coreaudio/macos/mod.rs index 7b53a40a5..60bbf88c0 100644 --- a/src/host/coreaudio/macos/mod.rs +++ b/src/host/coreaudio/macos/mod.rs @@ -34,16 +34,14 @@ pub use device::Device; #[derive(Debug)] pub struct Host; -impl Host { - pub fn new() -> Result { - Ok(Host) - } -} - impl HostTrait for Host { type Devices = Devices; type Device = Device; + fn new() -> Result { + Ok(Host) + } + fn is_available() -> bool { // Assume coreaudio is always available true diff --git a/src/host/custom/mod.rs b/src/host/custom/mod.rs index 2de8b5ff8..0a527f7ea 100644 --- a/src/host/custom/mod.rs +++ b/src/host/custom/mod.rs @@ -28,11 +28,6 @@ use crate::{ pub struct Host(Box); impl Host { - // this only exists for impl_platform_host, which requires it - pub(crate) fn new() -> Result { - Err(Error::new(ErrorKind::HostUnavailable)) - } - /// Construct a custom host from an arbitrary [`HostTrait`] implementation. pub fn from_host(host: T) -> Self where @@ -356,6 +351,10 @@ impl HostTrait for Host { type Devices = Devices; type Device = Device; + fn new() -> Result { + Err(Error::new(ErrorKind::HostUnavailable)) + } + fn is_available() -> bool { false } diff --git a/src/host/jack/mod.rs b/src/host/jack/mod.rs index 7360ccbb6..b21d740fd 100644 --- a/src/host/jack/mod.rs +++ b/src/host/jack/mod.rs @@ -44,17 +44,6 @@ pub struct Host { } impl Host { - pub fn new() -> Result { - let mut host = Host { - name: format!("cpal_client_{}", std::process::id()), - connect_ports_automatically: true, - start_server_automatically: false, - devices_created: vec![], - }; - // Devices don't exist for JACK, they have to be created - host.initialize_default_devices(); - Ok(host) - } /// Configures whether created ports should automatically connect to system playback/capture /// ports. /// @@ -113,6 +102,18 @@ impl HostTrait for Host { type Devices = Devices; type Device = Device; + fn new() -> Result { + let mut host = Host { + name: format!("cpal_client_{}", std::process::id()), + connect_ports_automatically: true, + start_server_automatically: false, + devices_created: vec![], + }; + // Devices don't exist for JACK, they have to be created + host.initialize_default_devices(); + Ok(host) + } + /// JACK is available if /// - the jack feature flag is set /// - libjack is installed (wouldn't compile without it) diff --git a/src/host/null/mod.rs b/src/host/null/mod.rs index 2cce813f3..5c697e072 100644 --- a/src/host/null/mod.rs +++ b/src/host/null/mod.rs @@ -33,13 +33,6 @@ pub struct SupportedInputConfigs; #[derive(Clone)] pub struct SupportedOutputConfigs; -impl Host { - #[allow(dead_code)] - pub fn new() -> Result { - Ok(Self) - } -} - impl DeviceTrait for Device { type SupportedInputConfigs = SupportedInputConfigs; type SupportedOutputConfigs = SupportedOutputConfigs; @@ -105,6 +98,10 @@ impl HostTrait for Host { type Devices = Devices; type Device = Device; + fn new() -> Result { + Ok(Self) + } + fn is_available() -> bool { false } diff --git a/src/host/pipewire/mod.rs b/src/host/pipewire/mod.rs index 412dd3d5c..fb7511d99 100644 --- a/src/host/pipewire/mod.rs +++ b/src/host/pipewire/mod.rs @@ -29,19 +29,6 @@ pub struct Host { } impl Host { - pub fn new() -> Result { - let _pw = PwInitGuard::new(); - let connect_automatically = Arc::new(AtomicBool::new(true)); - let devices = init_devices(connect_automatically.clone()).ok_or_else(|| { - Error::with_message(ErrorKind::HostUnavailable, "PipeWire is not available") - })?; - Ok(Self { - _pw, - devices, - connect_automatically, - }) - } - /// Configures whether created streams should automatically connect to system playback/capture /// nodes via the session manager. /// @@ -60,6 +47,19 @@ impl HostTrait for Host { type Devices = Devices; type Device = Device; + fn new() -> Result { + let _pw = PwInitGuard::new(); + let connect_automatically = Arc::new(AtomicBool::new(true)); + let devices = init_devices(connect_automatically.clone()).ok_or_else(|| { + Error::with_message(ErrorKind::HostUnavailable, "PipeWire is not available") + })?; + Ok(Self { + _pw, + devices, + connect_automatically, + }) + } + fn is_available() -> bool { utils::find_socket_path().is_some() } diff --git a/src/host/pulseaudio/mod.rs b/src/host/pulseaudio/mod.rs index 6a0280b78..d02712d7b 100644 --- a/src/host/pulseaudio/mod.rs +++ b/src/host/pulseaudio/mod.rs @@ -128,8 +128,11 @@ pub struct Host { client: pulseaudio::Client, } -impl Host { - pub fn new() -> Result { +impl HostTrait for Host { + type Devices = std::vec::IntoIter; + type Device = Device; + + fn new() -> Result { // `Client::from_env` does a blocking auth handshake with no socket timeout. If this never // returns, fall through to the next host with no other option than to leak the thread. let (tx, rx) = mpsc::channel(); @@ -153,11 +156,6 @@ impl Host { Ok(Self { client }) } -} - -impl HostTrait for Host { - type Devices = std::vec::IntoIter; - type Device = Device; fn is_available() -> bool { pulseaudio::socket_path_from_env().is_some() diff --git a/src/host/wasapi/mod.rs b/src/host/wasapi/mod.rs index 999d1ab86..487e936d0 100644 --- a/src/host/wasapi/mod.rs +++ b/src/host/wasapi/mod.rs @@ -32,16 +32,14 @@ mod stream; #[derive(Debug)] pub struct Host; -impl Host { - pub fn new() -> Result { - Ok(Host) - } -} - impl HostTrait for Host { type Devices = Devices; type Device = Device; + fn new() -> Result { + Ok(Host) + } + fn is_available() -> bool { // Assume WASAPI is always available on Windows. true diff --git a/src/host/webaudio/mod.rs b/src/host/webaudio/mod.rs index f8cc3d700..4d1649984 100644 --- a/src/host/webaudio/mod.rs +++ b/src/host/webaudio/mod.rs @@ -157,8 +157,11 @@ const SCRIPT_PROCESSOR_VALID_BUFFER_SIZES: [usize; 7] = [256, 512, 1024, 2048, 4 const SCRIPT_PROCESSOR_MIN_BUFFER_SIZE: usize = 256; const SCRIPT_PROCESSOR_MAX_BUFFER_SIZE: usize = 16384; -impl Host { - pub fn new() -> Result { +impl HostTrait for Host { + type Devices = Devices; + type Device = Device; + + fn new() -> Result { if Self::is_available() { Ok(Self) } else { @@ -168,11 +171,6 @@ impl Host { )) } } -} - -impl HostTrait for Host { - type Devices = Devices; - type Device = Device; fn is_available() -> bool { is_webaudio_available() diff --git a/src/platform/mod.rs b/src/platform/mod.rs index fc859a267..41875bc82 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -581,6 +581,19 @@ macro_rules! impl_platform_host { false } + fn new() -> Result + where + Self: Sized, + { + $( + $(#[cfg($feat)])? + if let Ok(host) = <$Host>::new() { + return Ok(host.into()); + } + )* + Err(crate::Error::new(crate::ErrorKind::HostUnavailable)) + } + fn devices(&self) -> Result { match self.0 { $( @@ -874,6 +887,7 @@ mod platform_impl { use crate::host::pipewire::Host as PipeWireHost; #[cfg(feature = "pulseaudio")] use crate::host::pulseaudio::Host as PulseAudioHost; + use crate::traits::HostTrait as _; impl_platform_host!( #[cfg(feature = "pipewire")] PipeWire => PipeWireHost, #[cfg(feature = "pulseaudio")] PulseAudio => PulseAudioHost, @@ -907,6 +921,7 @@ mod platform_impl { #[cfg(all(feature = "jack", target_os = "macos"))] use super::JackHost; use crate::host::coreaudio::Host as CoreAudioHost; + use crate::traits::HostTrait as _; impl_platform_host!( CoreAudio => CoreAudioHost, @@ -962,6 +977,7 @@ mod platform_impl { #[cfg(feature = "asio")] use crate::host::asio::Host as AsioHost; use crate::host::wasapi::Host as WasapiHost; + use crate::traits::HostTrait as _; impl_platform_host!( #[cfg(feature = "asio")] Asio "ASIO" => AsioHost, @@ -981,6 +997,7 @@ mod platform_impl { #[cfg(target_os = "android")] mod platform_impl { use crate::host::aaudio::Host as AAudioHost; + use crate::traits::HostTrait as _; impl_platform_host!( AAudio => AAudioHost, #[cfg(feature = "custom")] Custom => super::CustomHost @@ -994,6 +1011,7 @@ mod platform_impl { } } +// A compilation on a platform with no known host backends #[cfg(not(any( windows, target_os = "linux", @@ -1010,6 +1028,7 @@ mod platform_impl { )))] mod platform_impl { use crate::host::null::Host as NullHost; + use crate::traits::HostTrait as _; impl_platform_host!( #[cfg(not(feature = "custom"))] Null => NullHost, diff --git a/src/traits.rs b/src/traits.rs index beeff09d2..69b5e65e7 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -48,6 +48,10 @@ pub trait HostTrait { /// Whether or not the host is available on the system. fn is_available() -> bool; + fn new() -> Result + where + Self: Sized; + /// An iterator yielding all [`Device`](DeviceTrait)s currently available to the host on the system. /// /// Can be empty if the system does not support audio in general. From a6632aefbce439a6c6d0e002dde050b1ff17109d Mon Sep 17 00:00:00 2001 From: Marco Farruggio Date: Mon, 14 Sep 2026 13:44:25 +0100 Subject: [PATCH 03/11] removed any panics from default host --- src/host/null/mod.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/host/null/mod.rs b/src/host/null/mod.rs index 5c697e072..6a2741326 100644 --- a/src/host/null/mod.rs +++ b/src/host/null/mod.rs @@ -47,19 +47,19 @@ impl DeviceTrait for Device { } fn supported_input_configs(&self) -> Result { - unimplemented!() + Error::with_message(DeviceNotAvailable, "Null host in use") } fn supported_output_configs(&self) -> Result { - unimplemented!() + Error::with_message(DeviceNotAvailable, "Null host in use") } fn default_input_config(&self) -> Result { - unimplemented!() + Error::with_message(DeviceNotAvailable, "Null host in use") } fn default_output_config(&self) -> Result { - unimplemented!() + Error::with_message(DeviceNotAvailable, "Null host in use") } fn build_input_stream_raw( @@ -74,7 +74,7 @@ impl DeviceTrait for Device { D: FnMut(&Data, &CallbackInfo) + Send + 'static, E: FnMut(Error) + Send + 'static, { - unimplemented!() + Error::with_message(DeviceNotAvailable, "Null host in use") } /// Create an output stream. @@ -90,7 +90,7 @@ impl DeviceTrait for Device { D: FnMut(&mut Data, &CallbackInfo) + Send + 'static, E: FnMut(Error) + Send + 'static, { - unimplemented!() + Error::with_message(DeviceNotAvailable, "Null host in use") } } @@ -121,23 +121,23 @@ impl HostTrait for Host { impl StreamTrait for Stream { fn start(&self) -> Result<(), Error> { - unimplemented!() + Error::with_message(DeviceNotAvailable, "Null host in use") } fn pause(&self) -> Result<(), Error> { - unimplemented!() + Error::with_message(DeviceNotAvailable, "Null host in use") } fn stop(&self, _timeout: Option) -> Result<(), Error> { - unimplemented!() + Error::with_message(DeviceNotAvailable, "Null host in use") } fn now(&self) -> StreamInstant { - unimplemented!() + StreamInstant::ZERO } fn buffer_size(&self) -> Result { - unimplemented!() + Error::with_message(DeviceNotAvailable, "Null host in use") } } From 3a6efedce8658e35fe856e2729a0dc169ee27a63 Mon Sep 17 00:00:00 2001 From: Marco Farruggio Date: Mon, 14 Sep 2026 13:49:27 +0100 Subject: [PATCH 04/11] replaced HostTrait scoping with explicit --- src/platform/mod.rs | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/platform/mod.rs b/src/platform/mod.rs index 41875bc82..f9fd05162 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -848,7 +848,7 @@ macro_rules! impl_platform_host { $( $(#[cfg($feat)])? HostId::$HostVariant => { - <$Host>::new() + <$Host as crate::traits::HostTrait>::new() .map(HostInner::$HostVariant) .map(Host::from) } @@ -887,7 +887,6 @@ mod platform_impl { use crate::host::pipewire::Host as PipeWireHost; #[cfg(feature = "pulseaudio")] use crate::host::pulseaudio::Host as PulseAudioHost; - use crate::traits::HostTrait as _; impl_platform_host!( #[cfg(feature = "pipewire")] PipeWire => PipeWireHost, #[cfg(feature = "pulseaudio")] PulseAudio => PulseAudioHost, @@ -900,17 +899,17 @@ mod platform_impl { pub fn default_host() -> Host { #[cfg(feature = "pipewire")] if ::is_available() { - if let Ok(host) = PipeWireHost::new() { + if let Ok(host) = ::new() { return host.into(); } } #[cfg(feature = "pulseaudio")] if ::is_available() { - if let Ok(host) = PulseAudioHost::new() { + if let Ok(host) = ::new() { return host.into(); } } - AlsaHost::new() + ::new() .expect("the default host should always be available") .into() } @@ -921,7 +920,6 @@ mod platform_impl { #[cfg(all(feature = "jack", target_os = "macos"))] use super::JackHost; use crate::host::coreaudio::Host as CoreAudioHost; - use crate::traits::HostTrait as _; impl_platform_host!( CoreAudio => CoreAudioHost, @@ -931,7 +929,7 @@ mod platform_impl { /// The default host for the current compilation target platform. pub fn default_host() -> Host { - CoreAudioHost::new() + ::new() .expect("the default host should always be available") .into() } @@ -946,7 +944,6 @@ mod platform_impl { #[cfg(all(feature = "audioworklet", target_feature = "atomics"))] use crate::host::audioworklet::Host as AudioWorkletHost; use crate::host::webaudio::Host as WebAudioHost; - use crate::traits::HostTrait as _; impl_platform_host!( WebAudio => WebAudioHost, @@ -962,11 +959,13 @@ mod platform_impl { /// where `AudioContext` is unavailable. pub fn default_host() -> Host { assert!( - WebAudioHost::is_available(), + ::is_available(), "WebAudio is not available in this context; \ AudioContext requires a Window (not a Worker or Service Worker)" ); - WebAudioHost::new().unwrap().into() + ::new() + .unwrap() + .into() } } @@ -977,7 +976,6 @@ mod platform_impl { #[cfg(feature = "asio")] use crate::host::asio::Host as AsioHost; use crate::host::wasapi::Host as WasapiHost; - use crate::traits::HostTrait as _; impl_platform_host!( #[cfg(feature = "asio")] Asio "ASIO" => AsioHost, @@ -988,7 +986,7 @@ mod platform_impl { /// The default host for the current compilation target platform. pub fn default_host() -> Host { - WasapiHost::new() + ::new() .expect("the default host should always be available") .into() } @@ -997,7 +995,6 @@ mod platform_impl { #[cfg(target_os = "android")] mod platform_impl { use crate::host::aaudio::Host as AAudioHost; - use crate::traits::HostTrait as _; impl_platform_host!( AAudio => AAudioHost, #[cfg(feature = "custom")] Custom => super::CustomHost @@ -1005,7 +1002,7 @@ mod platform_impl { /// The default host for the current compilation target platform. pub fn default_host() -> Host { - AAudioHost::new() + ::new() .expect("the default host should always be available") .into() } @@ -1028,7 +1025,6 @@ mod platform_impl { )))] mod platform_impl { use crate::host::null::Host as NullHost; - use crate::traits::HostTrait as _; impl_platform_host!( #[cfg(not(feature = "custom"))] Null => NullHost, @@ -1038,7 +1034,7 @@ mod platform_impl { /// The default host for the current compilation target platform. #[cfg(feature = "custom")] pub fn default_host() -> Host { - CustomHost::new() + ::new() .expect("the default host should always be available") .into() } @@ -1046,7 +1042,7 @@ mod platform_impl { /// The default host for the current compilation target platform. #[cfg(not(feature = "custom"))] pub fn default_host() -> Host { - NullHost::new() + ::new() .expect("the default host should always be available") .into() } From 76b12ac2bec85fd4dfee1af8504659efc5ec7bbe Mon Sep 17 00:00:00 2001 From: Marco Farruggio Date: Mon, 14 Sep 2026 17:03:46 +0100 Subject: [PATCH 05/11] fixed an exmaple, and cargo formatting --- examples/custom.rs | 4 ++++ src/platform/mod.rs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/custom.rs b/examples/custom.rs index 2f0e73d14..83f6af9c0 100644 --- a/examples/custom.rs +++ b/examples/custom.rs @@ -48,6 +48,10 @@ impl HostTrait for MyHost { true } + fn new() -> Result { + Ok(Self) + } + fn devices(&self) -> Result { Ok(std::iter::once(MyDevice)) } diff --git a/src/platform/mod.rs b/src/platform/mod.rs index f9fd05162..713ddc14f 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -986,7 +986,7 @@ mod platform_impl { /// The default host for the current compilation target platform. pub fn default_host() -> Host { - ::new() + ::new() .expect("the default host should always be available") .into() } From 96a0408d5e5dc9ddf0c888b98a454882dd1d06c8 Mon Sep 17 00:00:00 2001 From: Marco Farruggio Date: Mon, 14 Sep 2026 17:07:41 +0100 Subject: [PATCH 06/11] brought errorkind into scope --- src/host/null/mod.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/host/null/mod.rs b/src/host/null/mod.rs index 6a2741326..635388f29 100644 --- a/src/host/null/mod.rs +++ b/src/host/null/mod.rs @@ -6,8 +6,10 @@ use std::fmt; use std::time::Duration; use crate::{ - CallbackInfo, Data, DeviceDescription, DeviceDescriptionBuilder, DeviceId, Error, FrameCount, - SampleFormat, StreamConfig, StreamInstant, SupportedStreamConfig, SupportedStreamConfigRange, + CallbackInfo, Data, DeviceDescription, DeviceDescriptionBuilder, DeviceId, Error, + ErrorKind::DeviceNotAvailable, + FrameCount, SampleFormat, StreamConfig, StreamInstant, SupportedStreamConfig, + SupportedStreamConfigRange, traits::{DeviceTrait, HostTrait, StreamTrait}, }; From 21766093cbf64b5547c471798a239de4b21e176f Mon Sep 17 00:00:00 2001 From: Marco Farruggio Date: Mon, 14 Sep 2026 17:15:34 +0100 Subject: [PATCH 07/11] ensure correct return types --- src/host/null/mod.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/host/null/mod.rs b/src/host/null/mod.rs index 635388f29..d1e86b199 100644 --- a/src/host/null/mod.rs +++ b/src/host/null/mod.rs @@ -49,19 +49,19 @@ impl DeviceTrait for Device { } fn supported_input_configs(&self) -> Result { - Error::with_message(DeviceNotAvailable, "Null host in use") + Err(Error::with_message(DeviceNotAvailable, "Null host in use")) } fn supported_output_configs(&self) -> Result { - Error::with_message(DeviceNotAvailable, "Null host in use") + Err(Error::with_message(DeviceNotAvailable, "Null host in use")) } fn default_input_config(&self) -> Result { - Error::with_message(DeviceNotAvailable, "Null host in use") + Err(Error::with_message(DeviceNotAvailable, "Null host in use")) } fn default_output_config(&self) -> Result { - Error::with_message(DeviceNotAvailable, "Null host in use") + Err(Error::with_message(DeviceNotAvailable, "Null host in use")) } fn build_input_stream_raw( @@ -76,7 +76,7 @@ impl DeviceTrait for Device { D: FnMut(&Data, &CallbackInfo) + Send + 'static, E: FnMut(Error) + Send + 'static, { - Error::with_message(DeviceNotAvailable, "Null host in use") + Err(Error::with_message(DeviceNotAvailable, "Null host in use")) } /// Create an output stream. @@ -92,7 +92,7 @@ impl DeviceTrait for Device { D: FnMut(&mut Data, &CallbackInfo) + Send + 'static, E: FnMut(Error) + Send + 'static, { - Error::with_message(DeviceNotAvailable, "Null host in use") + Err(Error::with_message(DeviceNotAvailable, "Null host in use")) } } @@ -123,15 +123,15 @@ impl HostTrait for Host { impl StreamTrait for Stream { fn start(&self) -> Result<(), Error> { - Error::with_message(DeviceNotAvailable, "Null host in use") + Err(Error::with_message(DeviceNotAvailable, "Null host in use")) } fn pause(&self) -> Result<(), Error> { - Error::with_message(DeviceNotAvailable, "Null host in use") + Err(Error::with_message(DeviceNotAvailable, "Null host in use")) } fn stop(&self, _timeout: Option) -> Result<(), Error> { - Error::with_message(DeviceNotAvailable, "Null host in use") + Err(Error::with_message(DeviceNotAvailable, "Null host in use")) } fn now(&self) -> StreamInstant { @@ -139,7 +139,7 @@ impl StreamTrait for Stream { } fn buffer_size(&self) -> Result { - Error::with_message(DeviceNotAvailable, "Null host in use") + Err(Error::with_message(DeviceNotAvailable, "Null host in use")) } } From 418c6ed49567b84138a8c7c1f5a49cca6c9e3c5e Mon Sep 17 00:00:00 2001 From: Marco Farruggio Date: Mon, 14 Sep 2026 17:19:15 +0100 Subject: [PATCH 08/11] fix scoping.... an IDE which decided to lint today would be lovely --- src/platform/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/platform/mod.rs b/src/platform/mod.rs index 713ddc14f..8b5d3d251 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -1024,7 +1024,10 @@ mod platform_impl { ), )))] mod platform_impl { + #[cfg(not(feature = "custom"))] use crate::host::null::Host as NullHost; + #[cfg(feature = "custom")] + use crate::host::custom::Host as CustomHost; impl_platform_host!( #[cfg(not(feature = "custom"))] Null => NullHost, From 49501c2b225644fd3db5d10a0a7f9d2d24f1974d Mon Sep 17 00:00:00 2001 From: Marco Farruggio Date: Mon, 14 Sep 2026 17:41:31 +0100 Subject: [PATCH 09/11] fixed null imports --- src/host/mod.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/host/mod.rs b/src/host/mod.rs index b1df58e1d..f540171a0 100644 --- a/src/host/mod.rs +++ b/src/host/mod.rs @@ -86,7 +86,9 @@ pub(crate) mod webaudio; #[cfg(feature = "custom")] pub(crate) mod custom; -#[cfg(not(any( +#[cfg(all( + not(feature = "custom"), + not(any( windows, target_os = "linux", target_os = "dragonfly", @@ -99,7 +101,8 @@ pub(crate) mod custom; target_os = "unknown", feature = "wasm-bindgen" ), -)))] + )), +))] pub(crate) mod null; #[cfg(any( From 4810ac72633285861a43a4ca2c0aed1ae44540ba Mon Sep 17 00:00:00 2001 From: Marco Farruggio Date: Mon, 14 Sep 2026 17:43:41 +0100 Subject: [PATCH 10/11] formatting fixes --- src/host/mod.rs | 24 ++++++++++++------------ src/platform/mod.rs | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/host/mod.rs b/src/host/mod.rs index f540171a0..71352a5cc 100644 --- a/src/host/mod.rs +++ b/src/host/mod.rs @@ -89,18 +89,18 @@ pub(crate) mod custom; #[cfg(all( not(feature = "custom"), not(any( - windows, - target_os = "linux", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_vendor = "apple", - target_os = "android", - all( - target_arch = "wasm32", - target_os = "unknown", - feature = "wasm-bindgen" - ), + windows, + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_vendor = "apple", + target_os = "android", + all( + target_arch = "wasm32", + target_os = "unknown", + feature = "wasm-bindgen" + ), )), ))] pub(crate) mod null; diff --git a/src/platform/mod.rs b/src/platform/mod.rs index 8b5d3d251..d5654c2e5 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -1024,10 +1024,10 @@ mod platform_impl { ), )))] mod platform_impl { - #[cfg(not(feature = "custom"))] - use crate::host::null::Host as NullHost; #[cfg(feature = "custom")] use crate::host::custom::Host as CustomHost; + #[cfg(not(feature = "custom"))] + use crate::host::null::Host as NullHost; impl_platform_host!( #[cfg(not(feature = "custom"))] Null => NullHost, From 7044eaa9f5bb55500d4a1a8862230e0aa14c2f3f Mon Sep 17 00:00:00 2001 From: Marco Farruggio Date: Mon, 14 Sep 2026 18:38:26 +0100 Subject: [PATCH 11/11] fixed compiling null on non-null targets --- src/host/mod.rs | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/host/mod.rs b/src/host/mod.rs index 34a92488d..76ec64c45 100644 --- a/src/host/mod.rs +++ b/src/host/mod.rs @@ -86,20 +86,23 @@ pub(crate) mod webaudio; #[cfg(feature = "custom")] pub(crate) mod custom; -#[cfg(not(any( - windows, - target_os = "linux", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_vendor = "apple", - target_os = "android", - all( - target_arch = "wasm32", - any(target_os = "emscripten", target_os = "unknown"), - feature = "wasm-bindgen" - ), -)))] +#[cfg(all( + not(feature = "custom"), + not(any( + windows, + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_vendor = "apple", + target_os = "android", + all( + target_arch = "wasm32", + any(target_os = "emscripten", target_os = "unknown"), + feature = "wasm-bindgen" + ), + )), +))] pub(crate) mod null; #[cfg(any(