pub mod srt;
pub mod ssa;
pub mod idx;
pub mod microdvd;
pub mod vobsub;
pub mod common;
use SubtitleFile;
use encoding::{EncodingRef, DecoderTrap};
use errors::*;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum SubtitleFormat {
SubRip,
SubStationAlpha,
VobSubIdx,
VobSubSub,
MicroDVD,
}
impl SubtitleFormat {
pub fn get_name(&self) -> &'static str {
match *self {
SubtitleFormat::SubRip => ".srt (SubRip)",
SubtitleFormat::SubStationAlpha => ".ssa (SubStation Alpha)",
SubtitleFormat::VobSubIdx => ".idx (VobSub)",
SubtitleFormat::VobSubSub => ".sub (VobSub)",
SubtitleFormat::MicroDVD => ".sub (MicroDVD)",
}
}
}
pub fn get_subtitle_format_by_ending(ending: &str) -> Option<SubtitleFormat> {
if ending.ends_with(".srt") {
Some(SubtitleFormat::SubRip)
} else if ending.ends_with(".ssa") || ending.ends_with(".ass") {
Some(SubtitleFormat::SubStationAlpha)
} else if ending.ends_with(".idx") {
Some(SubtitleFormat::VobSubIdx)
} else {
None
}
}
pub fn get_subtitle_format_by_ending_err(ending: &str) -> Result<SubtitleFormat> {
get_subtitle_format_by_ending(ending).ok_or_else(|| ErrorKind::UnknownFileFormat.into())
}
pub fn get_subtitle_format(ending: &str, content: &[u8]) -> Option<SubtitleFormat> {
if ending.ends_with(".sub") {
if content.iter().take(4).cloned().eq(
[0x00, 0x00, 0x01, 0xba]
.iter()
.cloned(),
)
{
Some(SubtitleFormat::VobSubSub)
} else {
Some(SubtitleFormat::MicroDVD)
}
} else {
get_subtitle_format_by_ending(ending)
}
}
pub fn get_subtitle_format_err(ending: &str, content: &[u8]) -> Result<SubtitleFormat> {
get_subtitle_format(ending, content).ok_or_else(|| ErrorKind::UnknownFileFormat.into())
}
pub trait ClonableSubtitleFile: SubtitleFile + Send + Sync {
fn clone_box(&self) -> Box<ClonableSubtitleFile>;
}
impl<T> ClonableSubtitleFile for T
where
T: SubtitleFile + Clone + Send + Sync + 'static,
{
fn clone_box(&self) -> Box<ClonableSubtitleFile> {
Box::new(Clone::clone(self))
}
}
impl Clone for Box<ClonableSubtitleFile> {
fn clone(&self) -> Box<ClonableSubtitleFile> {
self.clone_box()
}
}
pub fn parse_str(format: SubtitleFormat, content: &str, fps: f64) -> Result<Box<ClonableSubtitleFile>> {
match format {
SubtitleFormat::SubRip => Ok(Box::new(srt::SrtFile::parse(content)?)),
SubtitleFormat::SubStationAlpha => Ok(Box::new(ssa::SsaFile::parse(content)?)),
SubtitleFormat::VobSubIdx => Ok(Box::new(idx::IdxFile::parse(content)?)),
SubtitleFormat::VobSubSub => Err(ErrorKind::TextFormatOnly.into()),
SubtitleFormat::MicroDVD => Ok(Box::new(microdvd::MdvdFile::parse(content, fps)?)),
}
}
fn decode_bytes_to_string(content: &[u8], encoding: EncodingRef) -> Result<String> {
encoding.decode(content, DecoderTrap::Strict)
.map_err(|e| Error::from(e.to_string()))
.chain_err(|| Error::from(ErrorKind::DecodingError))
}
pub fn parse_bytes(format: SubtitleFormat, content: &[u8], encoding: EncodingRef, fps: f64) -> Result<Box<ClonableSubtitleFile>> {
match format {
SubtitleFormat::SubRip => Ok(Box::new(srt::SrtFile::parse(
&decode_bytes_to_string(content, encoding)?,
)?)),
SubtitleFormat::SubStationAlpha => Ok(Box::new(ssa::SsaFile::parse(
&decode_bytes_to_string(content, encoding)?,
)?)),
SubtitleFormat::VobSubIdx => Ok(Box::new(idx::IdxFile::parse(
&decode_bytes_to_string(content, encoding)?,
)?)),
SubtitleFormat::VobSubSub => Ok(Box::new(vobsub::VobFile::parse(content)?)),
SubtitleFormat::MicroDVD => Ok(Box::new(microdvd::MdvdFile::parse(
&decode_bytes_to_string(content, encoding)?,
fps,
)?)),
}
}