From fc3d6745ff9e35d163d6c6ac7fbab217318f9d39 Mon Sep 17 00:00:00 2001 From: Gwen Lg Date: Sat, 8 Mar 2025 22:42:18 +0100 Subject: [PATCH] feat(vobsub)!: make Index optional. `sub` file parsing don't need `idx`, so separate `sub` data from `idx`. Create a new Sub struct who can initialized from file, and contain the content of the `sub`. Remove `sub_data` from `Index` struct. --- src/vobsub/idx.rs | 8 +------- src/vobsub/mod.rs | 2 +- src/vobsub/sub.rs | 49 ++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/vobsub/idx.rs b/src/vobsub/idx.rs index f32b6de..557f56d 100644 --- a/src/vobsub/idx.rs +++ b/src/vobsub/idx.rs @@ -13,7 +13,7 @@ use crate::vobsub::IResultExt; use super::{ palette::{palette, DEFAULT_PALETTE}, - sub, Palette, VobSubError, + Palette, VobSubError, }; /// A `*.idx` file describing the subtitles in a `*.sub` file. @@ -81,12 +81,6 @@ impl Index { pub const fn palette(&self) -> &Palette { &self.palette } - - /// Iterate over the subtitles associated with this `*.idx` file. - #[must_use] - pub fn subtitles(&self) -> sub::VobsubParser { - sub::VobsubParser::new(&self.sub_data) - } } /// Read the palette in `*.idx` file content diff --git a/src/vobsub/mod.rs b/src/vobsub/mod.rs index 3ba6b3b..433f85c 100644 --- a/src/vobsub/mod.rs +++ b/src/vobsub/mod.rs @@ -79,7 +79,7 @@ pub use self::{ img::{conv_to_rgba, VobSubIndexedImage, VobSubOcrImage, VobSubToImage}, palette::{palette, palette_rgb_to_luminance, Palette}, probe::{is_idx_file, is_sub_file}, - sub::ErrorMissing, + sub::{ErrorMissing, Sub}, }; use crate::content::ContentError; diff --git a/src/vobsub/sub.rs b/src/vobsub/sub.rs index d3cb5ad..7857017 100644 --- a/src/vobsub/sub.rs +++ b/src/vobsub/sub.rs @@ -27,7 +27,9 @@ use nom::{ sequence::{preceded, Tuple}, IResult, }; -use std::{cmp::Ordering, fmt::Debug, iter::FusedIterator, marker::PhantomData}; +use std::{ + cmp::Ordering, fmt::Debug, fs, io::Read, iter::FusedIterator, marker::PhantomData, path::Path, +}; use thiserror::Error; /// Parse four 4-bit palette entries. @@ -319,6 +321,41 @@ macro_rules! try_iter { }; } +/// Store the content of a `*.sub` file. +pub struct Sub { + /// Our compressed subtitle data. + data: Vec, +} +impl Sub { + /// Init a `Sub` from a file path. + /// + /// # Errors + /// + /// Will return `VobSubError::Io` if not able to read a file from `path`. + pub fn open

(path: P) -> Result + where + P: AsRef + Clone, + { + let mut sub = fs::File::open(path.as_ref()).map_err(|source| VobSubError::Io { + source, + path: path.as_ref().to_path_buf(), + })?; + let mut data = vec![]; + sub.read_to_end(&mut data) + .map_err(|source| VobSubError::Io { + source, + path: path.as_ref().to_path_buf(), + })?; + Ok(Self { data }) + } + + /// Iterate over the subtitles associated with this `*.idx` file. + #[must_use] + pub fn subtitles(&self) -> VobsubParser { + VobsubParser::new(&self.data) + } +} + /// An internal iterator over subtitles. These subtitles may not have a /// valid `end_time`, so we'll try to fix them up before letting the user /// see them. @@ -414,7 +451,6 @@ impl FusedIterator for VobsubParser<'_, D> {} #[cfg(test)] mod tests { use super::*; - use crate::vobsub::idx; #[test] fn parse_palette_entries() { @@ -549,9 +585,9 @@ mod tests { #[test] fn parse_subtitles_from_subtitle_edit() { //use env_logger; - use idx::Index; + //let _ = env_logger::init(); - let idx = Index::open("./fixtures/tiny.idx").unwrap(); + let idx = Sub::open("./fixtures/tiny.sub").unwrap(); let mut subs = idx.subtitles::(); subs.next().expect("missing sub").unwrap(); assert!(subs.next().is_none()); @@ -560,18 +596,17 @@ mod tests { #[test] fn parse_fuzz_corpus_seeds() { //use env_logger; - use idx::Index; //let _ = env_logger::init(); // Make sure these two fuzz corpus inputs still work, and that they // return the same subtitle data. - let tiny = Index::open("./fixtures/tiny.idx") + let tiny = Sub::open("./fixtures/tiny.sub") .unwrap() .subtitles::() .next() .unwrap() .unwrap(); - let split = Index::open("./fixtures/tiny-split.idx") + let split = Sub::open("./fixtures/tiny-split.sub") .unwrap() .subtitles::() .next()