use std::convert::TryFrom;
use std::fmt;
use std::time::Duration;
use crate::ErrorKind;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum MediaType {
Movie = 0,
Normal = 1,
AudioBook = 2,
WhackedBookmark = 5,
MusicVideo = 6,
ShortFilm = 9,
TvShow = 10,
Booklet = 11,
}
impl MediaType {
const MOVIE: u8 = Self::Movie as u8;
const NORMAL: u8 = Self::Normal as u8;
const AUDIO_BOOK: u8 = Self::AudioBook as u8;
const WHACKED_BOOKMARK: u8 = Self::WhackedBookmark as u8;
const MUSIC_VIDEO: u8 = Self::MusicVideo as u8;
const SHORT_FILM: u8 = Self::ShortFilm as u8;
const TV_SHOW: u8 = Self::TvShow as u8;
const BOOKLET: u8 = Self::Booklet as u8;
pub fn code(&self) -> u8 {
*self as u8
}
}
impl TryFrom<u8> for MediaType {
type Error = crate::Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
Self::MOVIE => Ok(Self::Movie),
Self::NORMAL => Ok(Self::Normal),
Self::AUDIO_BOOK => Ok(Self::AudioBook),
Self::WHACKED_BOOKMARK => Ok(Self::WhackedBookmark),
Self::MUSIC_VIDEO => Ok(Self::MusicVideo),
Self::SHORT_FILM => Ok(Self::ShortFilm),
Self::TV_SHOW => Ok(Self::TvShow),
Self::BOOKLET => Ok(Self::Booklet),
_ => Err(Self::Error::new(ErrorKind::UnknownMediaType(value), "Unknown media type")),
}
}
}
impl fmt::Display for MediaType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Movie => write!(f, "Movie"),
Self::Normal => write!(f, "Normal"),
Self::AudioBook => write!(f, "Audiobook"),
Self::WhackedBookmark => write!(f, "Whacked Bookmark"),
Self::MusicVideo => write!(f, "Music Video"),
Self::ShortFilm => write!(f, "Short Film"),
Self::TvShow => write!(f, "TV-Show"),
Self::Booklet => write!(f, "Booklet"),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum AdvisoryRating {
Clean = 2,
Inoffensive = 0,
Explicit = 4,
}
impl AdvisoryRating {
const CLEAN: u8 = Self::Clean as u8;
const INOFFENSIVE: u8 = Self::Inoffensive as u8;
pub fn code(&self) -> u8 {
*self as u8
}
}
impl From<u8> for AdvisoryRating {
fn from(rating: u8) -> Self {
match rating {
Self::CLEAN => Self::Clean,
Self::INOFFENSIVE => Self::Inoffensive,
_ => Self::Explicit,
}
}
}
impl fmt::Display for AdvisoryRating {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Clean => write!(f, "Clean"),
Self::Inoffensive => write!(f, "Inoffensive"),
Self::Explicit => write!(f, "Explicit"),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ChannelConfig {
Mono = 1,
Stereo = 2,
Three = 3,
Four = 4,
Five = 5,
FiveOne = 6,
SevenOne = 7,
}
impl ChannelConfig {
const MONO: u8 = Self::Mono as u8;
const STEREO: u8 = Self::Stereo as u8;
const THREE: u8 = Self::Three as u8;
const FOUR: u8 = Self::Four as u8;
const FIVE: u8 = Self::Five as u8;
const FIVE_ONE: u8 = Self::FiveOne as u8;
const SEVEN_ONE: u8 = Self::SevenOne as u8;
pub const fn channel_count(&self) -> u8 {
match self {
Self::Mono => 1,
Self::Stereo => 2,
Self::Three => 3,
Self::Four => 4,
Self::Five => 5,
Self::FiveOne => 6,
Self::SevenOne => 8,
}
}
}
impl TryFrom<u8> for ChannelConfig {
type Error = crate::Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
Self::MONO => Ok(Self::Mono),
Self::STEREO => Ok(Self::Stereo),
Self::THREE => Ok(Self::Three),
Self::FOUR => Ok(Self::Four),
Self::FIVE => Ok(Self::Five),
Self::FIVE_ONE => Ok(Self::FiveOne),
Self::SEVEN_ONE => Ok(Self::SevenOne),
_ => Err(Self::Error::new(
crate::ErrorKind::UnknownChannelConfig(value),
"Unknown channel config index",
)),
}
}
}
impl fmt::Display for ChannelConfig {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Mono => write!(f, "Mono"),
Self::Stereo => write!(f, "Stereo"),
Self::Three => write!(f, "3.0"),
Self::Four => write!(f, "4.0"),
Self::Five => write!(f, "5.0"),
Self::FiveOne => write!(f, "5.1"),
Self::SevenOne => write!(f, "7.1"),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum SampleRate {
Hz96000 = 0,
Hz88200 = 1,
Hz64000 = 2,
Hz48000 = 3,
Hz44100 = 4,
Hz32000 = 5,
Hz24000 = 6,
Hz22050 = 7,
Hz16000 = 8,
Hz12000 = 9,
Hz11025 = 10,
Hz8000 = 11,
Hz7350 = 12,
}
impl SampleRate {
const HZ_96000: u8 = Self::Hz96000 as u8;
const HZ_88200: u8 = Self::Hz88200 as u8;
const HZ_64000: u8 = Self::Hz64000 as u8;
const HZ_48000: u8 = Self::Hz48000 as u8;
const HZ_44100: u8 = Self::Hz44100 as u8;
const HZ_32000: u8 = Self::Hz32000 as u8;
const HZ_24000: u8 = Self::Hz24000 as u8;
const HZ_22050: u8 = Self::Hz22050 as u8;
const HZ_16000: u8 = Self::Hz16000 as u8;
const HZ_12000: u8 = Self::Hz12000 as u8;
const HZ_11025: u8 = Self::Hz11025 as u8;
const HZ_8000: u8 = Self::Hz8000 as u8;
const HZ_7350: u8 = Self::Hz7350 as u8;
pub const fn hz(&self) -> u32 {
match self {
Self::Hz96000 => 96000,
Self::Hz88200 => 88200,
Self::Hz64000 => 64000,
Self::Hz48000 => 48000,
Self::Hz44100 => 44100,
Self::Hz32000 => 32000,
Self::Hz24000 => 24000,
Self::Hz22050 => 22050,
Self::Hz16000 => 16000,
Self::Hz12000 => 12000,
Self::Hz11025 => 11025,
Self::Hz8000 => 8000,
Self::Hz7350 => 7350,
}
}
}
impl TryFrom<u8> for SampleRate {
type Error = crate::Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
Self::HZ_96000 => Ok(Self::Hz96000),
Self::HZ_88200 => Ok(Self::Hz88200),
Self::HZ_64000 => Ok(Self::Hz64000),
Self::HZ_48000 => Ok(Self::Hz48000),
Self::HZ_44100 => Ok(Self::Hz44100),
Self::HZ_32000 => Ok(Self::Hz32000),
Self::HZ_24000 => Ok(Self::Hz24000),
Self::HZ_22050 => Ok(Self::Hz22050),
Self::HZ_16000 => Ok(Self::Hz16000),
Self::HZ_12000 => Ok(Self::Hz12000),
Self::HZ_11025 => Ok(Self::Hz11025),
Self::HZ_8000 => Ok(Self::Hz8000),
Self::HZ_7350 => Ok(Self::Hz7350),
_ => Err(Self::Error::new(
crate::ErrorKind::UnknownSampleRate(value),
"Unknown sample rate index",
)),
}
}
}
impl fmt::Display for SampleRate {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}Hz", self.hz())
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct AudioInfo {
pub duration: Duration,
pub channel_config: Option<ChannelConfig>,
pub sample_rate: Option<SampleRate>,
pub max_bitrate: Option<u32>,
pub avg_bitrate: Option<u32>,
}
pub type ImgRef<'a> = Img<&'a [u8]>;
pub type ImgMut<'a> = Img<&'a mut Vec<u8>>;
pub type ImgBuf = Img<Vec<u8>>;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Img<T> {
pub fmt: ImgFmt,
pub data: T,
}
impl<T> Img<T> {
pub const fn new(fmt: ImgFmt, data: T) -> Self {
Self { fmt, data }
}
pub const fn bmp(data: T) -> Self {
Self::new(ImgFmt::Bmp, data)
}
pub const fn jpeg(data: T) -> Self {
Self::new(ImgFmt::Jpeg, data)
}
pub const fn png(data: T) -> Self {
Self::new(ImgFmt::Png, data)
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ImgFmt {
Bmp,
Jpeg,
Png,
}
impl ImgFmt {
#[must_use]
pub fn is_bmp(&self) -> bool {
matches!(self, Self::Bmp)
}
#[must_use]
pub fn is_jpeg(&self) -> bool {
matches!(self, Self::Jpeg)
}
#[must_use]
pub fn is_png(&self) -> bool {
matches!(self, Self::Png)
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct Chapter {
pub start: Duration,
pub title: String,
}
impl Chapter {
pub fn new(start: Duration, title: impl Into<String>) -> Self {
Self { start, title: title.into() }
}
}