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::subtitle_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 Format {
Srt,
WebVtt,
Ass,
Ssa,
Sub,
#[is_variant(ignore)]
Mpl2,
Lrc,
Smi,
Stl,
Sbv,
Ttml,
MovText,
DvdSub,
HdmvPgs,
DvbSub,
XSub,
Other(SmolStr),
}
impl Default for Format {
#[cfg_attr(not(tarpaulin), inline(always))]
fn default() -> Self {
Self::Other(SmolStr::new_inline(""))
}
}
impl Format {
#[inline(always)]
pub const fn is_mpl2(&self) -> bool {
matches!(self, Self::Mpl2)
}
pub fn as_str(&self) -> &str {
match self {
Self::Srt => "srt",
Self::WebVtt => "webvtt",
Self::Ass => "ass",
Self::Ssa => "ssa",
Self::Sub => "microdvd",
Self::Mpl2 => "mpl2",
Self::Lrc => "lrc",
Self::Smi => "sami",
Self::Stl => "stl",
Self::Sbv => "subviewer",
Self::Ttml => "ttml",
Self::MovText => "mov_text",
Self::DvdSub => "dvd_subtitle",
Self::HdmvPgs => "hdmv_pgs_subtitle",
Self::DvbSub => "dvb_subtitle",
Self::XSub => "xsub",
Self::Other(s) => s.as_str(),
}
}
#[inline(always)]
pub const fn as_extension(&self) -> &'static str {
match self {
Self::Srt => "srt",
Self::WebVtt => "vtt",
Self::Ass => "ass",
Self::Ssa => "ssa",
Self::Sub => "sub",
Self::Mpl2 => "mpl",
Self::Lrc => "lrc",
Self::Smi => "smi",
Self::Stl => "stl",
Self::Sbv => "sbv",
Self::Ttml => "ttml",
Self::MovText => "",
Self::DvdSub => "",
Self::HdmvPgs => "",
Self::DvbSub => "",
Self::XSub => "",
Self::Other(_) => "",
}
}
pub const fn is_image_based(&self) -> Option<bool> {
match self {
Self::DvdSub | Self::HdmvPgs | Self::DvbSub | Self::XSub => Some(true),
Self::Srt
| Self::WebVtt
| Self::Ass
| Self::Ssa
| Self::Sub
| Self::Mpl2
| Self::Lrc
| Self::Smi
| Self::Stl
| Self::Sbv
| Self::Ttml
| Self::MovText => Some(false),
Self::Other(_) => None,
}
}
pub fn other(slug: impl AsRef<str>) -> Self {
Self::Other(crate::parse::fold_owned(slug.as_ref()))
}
}
roster!(
Format,
"subtitle format",
[
Srt, WebVtt, Ass, Ssa, Sub, Mpl2, Lrc, Smi, Stl, Sbv, Ttml, MovText,
DvdSub, HdmvPgs, DvbSub, XSub
],
escape: Other
);
impl FromStr for Format {
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"srt" => Self::Srt,
b"webvtt" => Self::WebVtt,
b"ass" => Self::Ass,
b"ssa" => Self::Ssa,
b"microdvd" => Self::Sub,
b"mpl2" => Self::Mpl2,
b"lrc" => Self::Lrc,
b"sami" => Self::Smi,
b"stl" => Self::Stl,
b"subviewer" => Self::Sbv,
b"ttml" => Self::Ttml,
b"mov_text" => Self::MovText,
b"dvd_subtitle" => Self::DvdSub,
b"hdmv_pgs_subtitle" => Self::HdmvPgs,
b"dvb_subtitle" => Self::DvbSub,
b"xsub" => Self::XSub,
_ => Self::other(s),
})
}
}
#[cfg(test)]
mod tests;