The HostId enum currently depends very heavily on the features cpal is compiled with, as each variant is only available if the corresponding backend is supported in the current build. This means that writing code which can switch between different backends, or which even just wants to be aware of which backend is currently being used must convert it into a string, and work with that. This is error prone and laborious.
I propose changing the HostId to be #[non_exhaustive], and to include every backend which is supported by cpal under any possible combination of features. The SUPPORTED_HOSTS associated constant, and is_supported method will surface the same information as the ALL_HOSTS constant currently does before these changes, with is_supported being equivalent to being included in SUPPORTED_HOSTS. The available_hosts iterator method and is_available method will surface the same information that the available_hosts function currently exposes, without the mandatory Vec allocation.
The items HostId, ALL_HOSTS, available_hosts, default_host, and host_from_id will also be pulled out from behind any feature gates to improve the documentation UX, as they aren't feature-dependent. This does add another failure mode to host_from_id, that being passing the HostId of an unsupported backend, in which case it will return ErrorKind::UnsupportedOperation.
HostId is also given a Default implementation, which is equivalent to the id of the host returned by default_host. This is primarily for the sake of the implementation, as opposed to being something users are inspecting, but it may also be useful for that purpose.
I'm not necessarily proposing deprecating ALL_HOSTS and available_hosts, although they would be made redundant should this be implemented, so they could be deprecated.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
enum HostId {
AAudio,
Alsa,
Asio,
AudioWorklet,
CoreAudio,
Custom,
Jack,
Null,
Wasapi,
WebAudio,
}
impl HostId {
/// Every `HostId` supported by the current configuration of cpal.
const SUPPORTED_HOSTS: &[Self];
/// Returns `true` if the given host is supported by the current configuration of cpal.
const fn is_supported(&self) -> bool;
/// Returns `true` if the given host is currently available on this platform.
fn is_available(&self) -> bool;
/// Returns an iterator over the hosts which are currently available on this platform.
const fn available_hosts() -> AvailableHostsIter;
}
struct AvailableHostsIter { .. }
impl Iterator for AvailableHostsIter {
type Item = HostId;
...
}
impl Default for HostId { ... }
The
HostIdenum currently depends very heavily on the featurescpalis compiled with, as each variant is only available if the corresponding backend is supported in the current build. This means that writing code which can switch between different backends, or which even just wants to be aware of which backend is currently being used must convert it into a string, and work with that. This is error prone and laborious.I propose changing the
HostIdto be#[non_exhaustive], and to include every backend which is supported bycpalunder any possible combination of features. TheSUPPORTED_HOSTSassociated constant, andis_supportedmethod will surface the same information as theALL_HOSTSconstant currently does before these changes, withis_supportedbeing equivalent to being included inSUPPORTED_HOSTS. Theavailable_hostsiterator method andis_availablemethod will surface the same information that theavailable_hostsfunction currently exposes, without the mandatoryVecallocation.The items
HostId,ALL_HOSTS,available_hosts,default_host, andhost_from_idwill also be pulled out from behind any feature gates to improve the documentation UX, as they aren't feature-dependent. This does add another failure mode tohost_from_id, that being passing theHostIdof an unsupported backend, in which case it will returnErrorKind::UnsupportedOperation.HostIdis also given aDefaultimplementation, which is equivalent to the id of the host returned bydefault_host. This is primarily for the sake of the implementation, as opposed to being something users are inspecting, but it may also be useful for that purpose.I'm not necessarily proposing deprecating
ALL_HOSTSandavailable_hosts, although they would be made redundant should this be implemented, so they could be deprecated.