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::channel_layout")
)]
#[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 ChannelLayout {
Mono,
Stereo,
StereoDownmix,
Binaural,
Ch2_1,
Ch3_0,
Ch3_0Back,
Ch3_1,
Ch3_1_2,
Ch4_0,
Ch4_1,
Quad,
QuadSide,
Ch5_0,
Ch5_0Back,
Ch5_1,
Ch5_1Back,
Ch5_1_2,
Ch5_1_2Back,
Ch5_1_4Back,
Ch6_0,
Ch6_0Front,
Ch6_1,
Ch6_1Back,
Ch6_1Front,
Ch7_0,
Ch7_0Front,
Ch7_1,
Ch7_1Wide,
Ch7_1WideBack,
Ch7_1_2,
Ch7_1_4Back,
Ch7_2_3,
Ch9_1_4Back,
Ch9_1_6,
Ch22_2,
Hexagonal,
Octagonal,
Hexadecagonal,
Cube,
Ambisonic1,
Ambisonic2,
Ambisonic3,
Other(SmolStr),
}
impl Default for ChannelLayout {
#[inline]
fn default() -> Self {
Self::Other(SmolStr::new_inline(""))
}
}
impl ChannelLayout {
pub fn as_str(&self) -> &str {
match self {
Self::Mono => "mono",
Self::Stereo => "stereo",
Self::StereoDownmix => "downmix",
Self::Binaural => "binaural",
Self::Ch2_1 => "2.1",
Self::Ch3_0 => "3.0",
Self::Ch3_0Back => "3.0(back)",
Self::Ch3_1 => "3.1",
Self::Ch3_1_2 => "3.1.2",
Self::Ch4_0 => "4.0",
Self::Ch4_1 => "4.1",
Self::Quad => "quad",
Self::QuadSide => "quad(side)",
Self::Ch5_0 => "5.0(side)",
Self::Ch5_0Back => "5.0",
Self::Ch5_1 => "5.1(side)",
Self::Ch5_1Back => "5.1",
Self::Ch5_1_2 => "5.1.2",
Self::Ch5_1_2Back => "5.1.2(back)",
Self::Ch5_1_4Back => "5.1.4",
Self::Ch6_0 => "6.0",
Self::Ch6_0Front => "6.0(front)",
Self::Ch6_1 => "6.1",
Self::Ch6_1Back => "6.1(back)",
Self::Ch6_1Front => "6.1(front)",
Self::Ch7_0 => "7.0",
Self::Ch7_0Front => "7.0(front)",
Self::Ch7_1 => "7.1",
Self::Ch7_1Wide => "7.1(wide-side)",
Self::Ch7_1WideBack => "7.1(wide)",
Self::Ch7_1_2 => "7.1.2",
Self::Ch7_1_4Back => "7.1.4",
Self::Ch7_2_3 => "7.2.3",
Self::Ch9_1_4Back => "9.1.4",
Self::Ch9_1_6 => "9.1.6",
Self::Ch22_2 => "22.2",
Self::Hexagonal => "hexagonal",
Self::Octagonal => "octagonal",
Self::Hexadecagonal => "hexadecagonal",
Self::Cube => "cube",
Self::Ambisonic1 => "ambisonic1",
Self::Ambisonic2 => "ambisonic2",
Self::Ambisonic3 => "ambisonic3",
Self::Other(s) => s.as_str(),
}
}
pub fn other(slug: impl AsRef<str>) -> Self {
Self::Other(crate::parse::fold_owned(slug.as_ref()))
}
}
roster!(
ChannelLayout,
"channel layout",
[
Mono,
Stereo,
StereoDownmix,
Binaural,
Ch2_1,
Ch3_0,
Ch3_0Back,
Ch3_1,
Ch3_1_2,
Ch4_0,
Ch4_1,
Quad,
QuadSide,
Ch5_0,
Ch5_0Back,
Ch5_1,
Ch5_1Back,
Ch5_1_2,
Ch5_1_2Back,
Ch5_1_4Back,
Ch6_0,
Ch6_0Front,
Ch6_1,
Ch6_1Back,
Ch6_1Front,
Ch7_0,
Ch7_0Front,
Ch7_1,
Ch7_1Wide,
Ch7_1WideBack,
Ch7_1_2,
Ch7_1_4Back,
Ch7_2_3,
Ch9_1_4Back,
Ch9_1_6,
Ch22_2,
Hexagonal,
Octagonal,
Hexadecagonal,
Cube,
Ambisonic1,
Ambisonic2,
Ambisonic3
],
escape: Other
);
impl FromStr for ChannelLayout {
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"mono" => Self::Mono,
b"stereo" => Self::Stereo,
b"downmix" => Self::StereoDownmix,
b"binaural" => Self::Binaural,
b"2.1" => Self::Ch2_1,
b"3.0" => Self::Ch3_0,
b"3.0(back)" => Self::Ch3_0Back,
b"3.1" => Self::Ch3_1,
b"3.1.2" => Self::Ch3_1_2,
b"4.0" => Self::Ch4_0,
b"4.1" => Self::Ch4_1,
b"quad" => Self::Quad,
b"quad(side)" => Self::QuadSide,
b"5.0(side)" => Self::Ch5_0,
b"5.0" => Self::Ch5_0Back,
b"5.1(side)" => Self::Ch5_1,
b"5.1" => Self::Ch5_1Back,
b"5.1.2" => Self::Ch5_1_2,
b"5.1.2(back)" => Self::Ch5_1_2Back,
b"5.1.4" => Self::Ch5_1_4Back,
b"6.0" => Self::Ch6_0,
b"6.0(front)" => Self::Ch6_0Front,
b"6.1" => Self::Ch6_1,
b"6.1(back)" => Self::Ch6_1Back,
b"6.1(front)" => Self::Ch6_1Front,
b"7.0" => Self::Ch7_0,
b"7.0(front)" => Self::Ch7_0Front,
b"7.1" => Self::Ch7_1,
b"7.1(wide-side)" => Self::Ch7_1Wide,
b"7.1(wide)" => Self::Ch7_1WideBack,
b"7.1.2" => Self::Ch7_1_2,
b"7.1.4" => Self::Ch7_1_4Back,
b"7.2.3" => Self::Ch7_2_3,
b"9.1.4" => Self::Ch9_1_4Back,
b"9.1.6" => Self::Ch9_1_6,
b"22.2" => Self::Ch22_2,
b"hexagonal" => Self::Hexagonal,
b"octagonal" => Self::Octagonal,
b"hexadecagonal" => Self::Hexadecagonal,
b"cube" => Self::Cube,
b"ambisonic1" => Self::Ambisonic1,
b"ambisonic2" => Self::Ambisonic2,
b"ambisonic3" => Self::Ambisonic3,
_ => Self::other(s),
})
}
}
#[cfg(test)]
mod tests;