#[cfg(ffi_alsa··)]
use crate::CStr;
use crate::{_alsa_raw as _raw, c_int, impl_trait};
use crate::{PcmLayout, PcmSample, PcmSpec};
#[doc = crate::_tags!(audio linux error)]
#[doc = crate::_doc_meta!{
location("sys/device/audio"),
#[cfg(target_pointer_width = "64")]
test_size_of(AlsaError = 24|192),
}]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[allow(missing_docs)]
pub enum AlsaError {
Code(c_int),
Unconfigured,
LayoutUnconfigured,
LayoutMismatch { active: PcmLayout, expected: PcmLayout },
SampleMismatch { pcm: PcmSample, ty: PcmSample },
SpecMismatch { buffer: PcmSpec, stream: PcmSpec },
InvalidSpec(PcmSpec),
IncompleteFrames,
NoProgress,
FrameCountExceeded { read_or_written: usize, requested: usize },
TooManyChannels { count: usize, max: usize },
}
impl AlsaError {
#[must_use]
pub const fn code(code: c_int) -> Self {
Self::Code(code)
}
pub const fn result(code: c_int) -> Result<(), Self> {
if code < 0 { Err(Self::Code(code)) } else { Ok(()) }
}
#[must_use]
pub const fn unconfigured() -> Self {
Self::Unconfigured
}
#[must_use]
pub const fn layout_unconfigured() -> Self {
Self::LayoutUnconfigured
}
#[must_use]
pub const fn layout_mismatch(active: PcmLayout, expected: PcmLayout) -> Self {
Self::LayoutMismatch { active, expected }
}
#[must_use]
pub const fn sample_mismatch(pcm: PcmSample, ty: PcmSample) -> Self {
Self::SampleMismatch { pcm, ty }
}
#[must_use]
pub const fn spec_mismatch(buffer: PcmSpec, stream: PcmSpec) -> Self {
Self::SpecMismatch { buffer, stream }
}
#[must_use]
pub const fn invalid_spec(spec: PcmSpec) -> Self {
Self::InvalidSpec(spec)
}
#[must_use]
pub const fn incomplete_frames() -> Self {
Self::IncompleteFrames
}
#[must_use]
pub const fn no_progress() -> Self {
Self::NoProgress
}
#[must_use]
pub const fn frame_count_exceeded(read_or_written: usize, requested: usize) -> Self {
Self::FrameCountExceeded { read_or_written, requested }
}
#[must_use]
pub const fn too_many_channels(count: usize, max: usize) -> Self {
Self::TooManyChannels { count, max }
}
}
impl_trait![fmt::Display+Error for AlsaError |self, f| match *self {
Self::Code(code) => cfg_select! {
ffi_alsa·· => { unsafe {
let msg = _raw::snd_strerror(code);
if msg.is_null() {
write![f, "ALSA error {code}"]
} else if let Ok(msg) = CStr::from_ptr(msg).to_str() {
write![f, "ALSA error {code}: {msg}"]
} else {
write![f, "ALSA error {code}"]
}
}}
_ => write![f, "ALSA error {code}"],
},
Self::Unconfigured =>
f.write_str("ALSA PCM stream is not configured"),
Self::LayoutUnconfigured =>
f.write_str("ALSA PCM stream layout is not configured"),
Self::LayoutMismatch { active, expected } =>
write![f, "ALSA PCM layout mismatch: active {active}, expected {expected}"],
Self::SampleMismatch { pcm, ty } =>
write![f, "PCM sample mismatch: buffer uses {pcm}, Rust type implies {ty}"],
Self::SpecMismatch { buffer, stream } =>
write![f, "PCM spec mismatch: buffer {buffer}, stream {stream}"],
Self::InvalidSpec(spec) =>
write![f, "Invalid PCM spec: {spec}"],
Self::IncompleteFrames =>
f.write_str("PCM buffer does not contain complete frames"),
Self::NoProgress =>
f.write_str("ALSA PCM operation made no progress"),
Self::FrameCountExceeded { read_or_written, requested } =>
write![f, "ALSA PCM operation exceeded requested frames: got {read_or_written}, requested {requested}"],
Self::TooManyChannels { count, max } =>
write![f, "Too many PCM channels: got {count}, maximum supported here is {max}"],
}];