use crate::Error;
use super::*;
use derive_more::{Display, From};
use std::str::FromStr;
#[derive(Debug, Clone, PartialEq, Eq, Display, From)]
#[non_exhaustive]
pub enum AudioCodec {
AAC(AAC),
#[display("opus")]
Opus,
#[display("flac")]
Flac,
#[display("mp3")]
Mp3,
#[display("mp2")]
Mp2,
#[display("ac-3")]
Ac3,
#[display("ec-3")]
Ec3,
#[display("{_0}")]
Unknown(String),
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum AudioCodecKind {
AAC,
Opus,
Unknown,
Flac,
Mp3,
}
impl AudioCodec {
pub fn kind(&self) -> AudioCodecKind {
match self {
Self::AAC(_) => AudioCodecKind::AAC,
Self::Opus => AudioCodecKind::Opus,
Self::Flac => AudioCodecKind::Flac,
Self::Mp3 => AudioCodecKind::Mp3,
Self::Mp2 | Self::Ac3 | Self::Ec3 => AudioCodecKind::Unknown,
Self::Unknown(_) => AudioCodecKind::Unknown,
}
}
}
impl FromStr for AudioCodec {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.starts_with("mp4a.40.") {
return AAC::from_str(s).map(Into::into);
} else if s == "opus" {
return Ok(Self::Opus);
} else if s == "flac" {
return Ok(Self::Flac);
} else if s == "mp3" {
return Ok(Self::Mp3);
} else if s == "mp2" {
return Ok(Self::Mp2);
} else if s == "ac-3" {
return Ok(Self::Ac3);
} else if s == "ec-3" {
return Ok(Self::Ec3);
}
Ok(Self::Unknown(s.to_string()))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn flac_roundtrip() {
let codec = AudioCodec::from_str("flac").unwrap();
assert_eq!(codec, AudioCodec::Flac);
assert_eq!(codec.to_string(), "flac");
assert_eq!(codec.kind(), AudioCodecKind::Flac);
}
}