use core::str::FromStr;
use derive_more::{Display, IsVariant, TryUnwrap, Unwrap};
use smol_str::SmolStr;
#[cfg_attr(
feature = "quickcheck",
derive(::quickcheck_richderive::Arbitrary),
quickcheck(arbitrary = "crate::quickcheck_helpers::strings::sample_format")
)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, Display, IsVariant, Unwrap, TryUnwrap)]
#[display("{}", self.as_str())]
#[unwrap(ref, ref_mut)]
#[try_unwrap(ref, ref_mut)]
#[non_exhaustive]
pub enum SampleFormat {
U8,
S16,
S32,
Flt,
Dbl,
U8p,
S16p,
S32p,
Fltp,
Dblp,
S64,
S64p,
Other(SmolStr),
}
impl Default for SampleFormat {
#[cfg_attr(not(tarpaulin), inline(always))]
fn default() -> Self {
Self::Other(SmolStr::new_inline(""))
}
}
impl SampleFormat {
pub fn as_str(&self) -> &str {
match self {
Self::U8 => "u8",
Self::S16 => "s16",
Self::S32 => "s32",
Self::Flt => "flt",
Self::Dbl => "dbl",
Self::U8p => "u8p",
Self::S16p => "s16p",
Self::S32p => "s32p",
Self::Fltp => "fltp",
Self::Dblp => "dblp",
Self::S64 => "s64",
Self::S64p => "s64p",
Self::Other(s) => s.as_str(),
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn to_u32(&self) -> Option<u32> {
Some(match self {
Self::U8 => 0,
Self::S16 => 1,
Self::S32 => 2,
Self::Flt => 3,
Self::Dbl => 4,
Self::U8p => 5,
Self::S16p => 6,
Self::S32p => 7,
Self::Fltp => 8,
Self::Dblp => 9,
Self::S64 => 10,
Self::S64p => 11,
Self::Other(_) => return None,
})
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn from_u32(v: u32) -> Option<Self> {
Some(match v {
0 => Self::U8,
1 => Self::S16,
2 => Self::S32,
3 => Self::Flt,
4 => Self::Dbl,
5 => Self::U8p,
6 => Self::S16p,
7 => Self::S32p,
8 => Self::Fltp,
9 => Self::Dblp,
10 => Self::S64,
11 => Self::S64p,
_ => return None,
})
}
pub fn other(slug: impl AsRef<str>) -> Self {
Self::Other(crate::parse::fold_owned(slug.as_ref()))
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn is_planar(&self) -> bool {
matches!(
self,
Self::U8p | Self::S16p | Self::S32p | Self::Fltp | Self::Dblp | Self::S64p
)
}
}
impl FromStr for SampleFormat {
type Err = core::convert::Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut buf = [0u8; crate::parse::FOLD_CAP];
let folded = crate::parse::fold(s, &mut buf).unwrap_or(s.as_bytes());
Ok(match folded {
b"u8" => Self::U8,
b"s16" => Self::S16,
b"s32" => Self::S32,
b"flt" => Self::Flt,
b"dbl" => Self::Dbl,
b"u8p" => Self::U8p,
b"s16p" => Self::S16p,
b"s32p" => Self::S32p,
b"fltp" => Self::Fltp,
b"dblp" => Self::Dblp,
b"s64" => Self::S64,
b"s64p" => Self::S64p,
_ => Self::other(s),
})
}
}
#[cfg_attr(
feature = "quickcheck",
derive(::quickcheck_richderive::Arbitrary),
quickcheck(arbitrary = "crate::quickcheck_helpers::strings::audio_container_format")
)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, Display, IsVariant, Unwrap, TryUnwrap)]
#[display("{}", self.as_str())]
#[unwrap(ref, ref_mut)]
#[try_unwrap(ref, ref_mut)]
#[non_exhaustive]
pub enum ContainerFormat {
#[is_variant(ignore)]
Mp3,
Aac,
Flac,
Ogg,
Opus,
Wav,
Aiff,
Alac,
Wma,
Ape,
Wv,
Mka,
#[is_variant(ignore)]
M4a,
Caf,
Other(SmolStr),
}
impl Default for ContainerFormat {
#[inline]
fn default() -> Self {
Self::Other(SmolStr::new_inline(""))
}
}
impl ContainerFormat {
#[inline(always)]
pub const fn is_mp3(&self) -> bool {
matches!(self, Self::Mp3)
}
#[inline(always)]
pub const fn is_m4a(&self) -> bool {
matches!(self, Self::M4a)
}
pub fn as_str(&self) -> &str {
match self {
Self::Mp3 => "mp3",
Self::Aac => "aac",
Self::Flac => "flac",
Self::Ogg => "ogg",
Self::Opus => "opus",
Self::Wav => "wav",
Self::Aiff => "aiff",
Self::Alac => "alac",
Self::Wma => "wma",
Self::Ape => "ape",
Self::Wv => "wv",
Self::Mka => "mka",
Self::M4a => "m4a",
Self::Caf => "caf",
Self::Other(s) => s.as_str(),
}
}
#[inline(always)]
pub const fn as_extension(&self) -> &'static str {
match self {
Self::Mp3 => "mp3",
Self::Aac => "aac",
Self::Flac => "flac",
Self::Ogg => "ogg",
Self::Opus => "opus",
Self::Wav => "wav",
Self::Aiff => "aiff",
Self::Alac => "m4a",
Self::Wma => "wma",
Self::Ape => "ape",
Self::Wv => "wv",
Self::Mka => "mka",
Self::M4a => "m4a",
Self::Caf => "caf",
Self::Other(_) => "",
}
}
pub fn other(slug: impl AsRef<str>) -> Self {
Self::Other(crate::parse::fold_owned(slug.as_ref()))
}
}
impl FromStr for ContainerFormat {
type Err = core::convert::Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut buf = [0u8; crate::parse::FOLD_CAP];
let folded = crate::parse::fold(s, &mut buf).unwrap_or(s.as_bytes());
Ok(match folded {
b"mp3" => Self::Mp3,
b"aac" => Self::Aac,
b"flac" => Self::Flac,
b"ogg" => Self::Ogg,
b"opus" => Self::Opus,
b"wav" => Self::Wav,
b"aiff" => Self::Aiff,
b"alac" => Self::Alac,
b"wma" => Self::Wma,
b"ape" => Self::Ape,
b"wv" => Self::Wv,
b"mka" => Self::Mka,
b"m4a" => Self::M4a,
b"caf" => Self::Caf,
_ => Self::other(s),
})
}
}
#[cfg(test)]
mod tests;