Srt

Struct Srt 

Source
pub struct Srt<'a> { /* private fields */ }
Expand description

A collection of subtitles representing an SRT file.

Srt is the main type for working with subtitle data. You can either parse an existing SRT string with Srt::try_parse or build a new subtitle collection with Srt::new and Srt::add_subtitle.

§Lifetime

The 'a lifetime allows parsed subtitles to borrow text directly from the input string (zero-copy parsing). When building subtitles programmatically with owned String data, use Srt<'static>.

§Example

use skrt::{Srt, Timestamp};

let mut srt = Srt::new();

srt.add_subtitle(
    Timestamp::from_millis(0).unwrap(),
    Timestamp::from_millis(2000).unwrap(),
    "First subtitle&quot".into(),
);

srt.add_subtitle(
    Timestamp::from_millis(2500).unwrap(),
    Timestamp::from_millis(5000).unwrap(),
    "Second subtitle".into(),
);

println!("{}", srt.serialize());

Implementations§

Source§

impl<'a> Srt<'a>

Source

pub fn new() -> Srt<'a>

Constructs an empty Srt with no subtitles.

§Example
use skrt::Srt;

let srt = Srt::new();
assert!(srt.subtitles().is_empty());
Examples found in repository?
examples/timeshift.rs (line 4)
3fn main() {
4    let mut srt = Srt::new();
5
6    srt.add_subtitle(
7        Timestamp::from_millis(0).unwrap(),
8        Timestamp::from_millis(1000).unwrap(),
9        "First".into(),
10    );
11
12    srt.add_subtitle(
13        Timestamp::from_millis(1000).unwrap(),
14        Timestamp::from_millis(2000).unwrap(),
15        "Second".into(),
16    );
17
18    for sub in &mut srt {
19        sub.set_start(sub.start().shift_millis(300).unwrap());
20        sub.set_end(sub.end().shift_millis(300).unwrap());
21    }
22
23    println!("{}", srt.serialize());
24}
Source

pub fn subtitles(&self) -> &[Subtitle<'a>]

Returns a slice of all subtitles.

§Example
use skrt::Srt;

let data = "1\n00:00:00,000 --> 00:00:01,000\nHello\n\n";
let srt = Srt::try_parse(data).unwrap();

for sub in srt.subtitles() {
    println!("{}: {}", sub.start(), sub.text());
}
Source

pub fn iter(&self) -> Iter<'_, Subtitle<'a>>

Returns an iterator over the subtitles.

§Example
use skrt::Srt;

let data = "1\n00:00:00,000 --> 00:00:01,000\nHello\n\n2\n00:00:02,000 --> 00:00:03,000\nWorld\n\n";
let srt = Srt::try_parse(data).unwrap();

let texts: Vec<_> = srt.iter().map(|s| s.text()).collect();
assert_eq!(vec!["Hello", "World"], texts);
Source

pub fn iter_mut<'b>(&'b mut self) -> IterMut<'b, Subtitle<'a>>

Returns a mutable iterator over the subtitles.

This allows in-place modification of subtitles, such as adjusting timestamps or updating text.

§Example
use skrt::{Srt, Timestamp};

let data = "1\n00:00:00,000 --> 00:00:01,000\nHello\n\n";
let mut srt = Srt::try_parse(data).unwrap();

// Shift all subtitles forward by 5 seconds
for sub in srt.iter_mut() {
    sub.set_start(sub.start().shift_millis(5000).unwrap());
    sub.set_end(sub.end().shift_millis(5000).unwrap());
}

assert_eq!(5000, srt.subtitles()[0].start().to_millis());
Source

pub fn add_subtitle( &mut self, start: Timestamp, end: Timestamp, text: Cow<'a, str>, )

Adds a new subtitle to the end of the collection.

The sequence number is automatically assigned based on the current number of subtitles (i.e., the new subtitle gets the next number in sequence).

§Example
use skrt::{Srt, Timestamp};

let mut srt = Srt::new();

srt.add_subtitle(
    Timestamp::from_millis(0).unwrap(),
    Timestamp::from_millis(1000).unwrap(),
    "First".into(),
);

srt.add_subtitle(
    Timestamp::from_millis(1000).unwrap(),
    Timestamp::from_millis(2000).unwrap(),
    "Second".into(),
);

assert_eq!(2, srt.subtitles().len());
Examples found in repository?
examples/timeshift.rs (lines 6-10)
3fn main() {
4    let mut srt = Srt::new();
5
6    srt.add_subtitle(
7        Timestamp::from_millis(0).unwrap(),
8        Timestamp::from_millis(1000).unwrap(),
9        "First".into(),
10    );
11
12    srt.add_subtitle(
13        Timestamp::from_millis(1000).unwrap(),
14        Timestamp::from_millis(2000).unwrap(),
15        "Second".into(),
16    );
17
18    for sub in &mut srt {
19        sub.set_start(sub.start().shift_millis(300).unwrap());
20        sub.set_end(sub.end().shift_millis(300).unwrap());
21    }
22
23    println!("{}", srt.serialize());
24}
Source

pub fn try_parse(srt: &str) -> Result<Srt<'_>>

Parses an SRT-formatted string.

This performs zero-copy parsing where possible. Subtitle text is borrowed directly from the input string.

§Supported Variations
  • LF (\n) and CRLF (\r\n) line endings
  • Optional UTF-8 BOM at the start
  • Trailing whitespace after timestamp lines
  • Missing final blank line
§Errors

Returns an SrtError if the input is malformed. The error includes position information for debugging.

§Example
use skrt::Srt;

let data = r#"1
00:00:01,000 --> 00:00:04,000
Hello!

"#;

let srt = Srt::try_parse(data).unwrap();
assert_eq!(1, srt.subtitles().len());
Examples found in repository?
examples/parse.rs (line 14)
3fn main() {
4    let data = r#"2
500:00:01,000 --> 00:00:04,000
6Hello,
7
81
900:00:05,000 --> 00:00:08,000
10World!
11
12"#;
13
14    let mut srt = Srt::try_parse(data).unwrap();
15    srt.resequence();
16
17    println!("{srt:#?}");
18}
Source

pub fn resequence(&mut self)

Reassigns sequence numbers starting from 1.

This is useful after modifying the subtitle list (e.g., removing or reordering entries) to ensure sequence numbers are contiguous.

§Example
use skrt::{Srt, Timestamp};

let mut srt = Srt::new();
srt.add_subtitle(
    Timestamp::from_millis(0).unwrap(),
    Timestamp::from_millis(1000).unwrap(),
    "Hello".into(),
);

// After some modifications...
srt.resequence();

assert_eq!(1, srt.subtitles()[0].seq());
Examples found in repository?
examples/parse.rs (line 15)
3fn main() {
4    let data = r#"2
500:00:01,000 --> 00:00:04,000
6Hello,
7
81
900:00:05,000 --> 00:00:08,000
10World!
11
12"#;
13
14    let mut srt = Srt::try_parse(data).unwrap();
15    srt.resequence();
16
17    println!("{srt:#?}");
18}
Source

pub fn serialize(&self) -> String

Serializes the subtitles to an SRT-formatted string.

The output uses LF line endings. Each subtitle block is separated by a blank line.

§Example
use skrt::{Srt, Timestamp};

let mut srt = Srt::new();
srt.add_subtitle(
    Timestamp::from_millis(1000).unwrap(),
    Timestamp::from_millis(2000).unwrap(),
    "Hello, world!".into(),
);

let output = srt.serialize();
assert!(output.contains("00:00:01,000 --> 00:00:02,000"));
assert!(output.contains("Hello, world!"));
Examples found in repository?
examples/timeshift.rs (line 23)
3fn main() {
4    let mut srt = Srt::new();
5
6    srt.add_subtitle(
7        Timestamp::from_millis(0).unwrap(),
8        Timestamp::from_millis(1000).unwrap(),
9        "First".into(),
10    );
11
12    srt.add_subtitle(
13        Timestamp::from_millis(1000).unwrap(),
14        Timestamp::from_millis(2000).unwrap(),
15        "Second".into(),
16    );
17
18    for sub in &mut srt {
19        sub.set_start(sub.start().shift_millis(300).unwrap());
20        sub.set_end(sub.end().shift_millis(300).unwrap());
21    }
22
23    println!("{}", srt.serialize());
24}

Trait Implementations§

Source§

impl<'a> Clone for Srt<'a>

Source§

fn clone(&self) -> Srt<'a>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a> Debug for Srt<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a> Default for Srt<'a>

Source§

fn default() -> Srt<'a>

Returns the “default value” for a type. Read more
Source§

impl<'a, 'b> IntoIterator for &'b Srt<'a>

Source§

type Item = &'b Subtitle<'a>

The type of the elements being iterated over.
Source§

type IntoIter = Iter<'b, Subtitle<'a>>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
Source§

impl<'a, 'b> IntoIterator for &'b mut Srt<'a>

Source§

type Item = &'b mut Subtitle<'a>

The type of the elements being iterated over.
Source§

type IntoIter = IterMut<'b, Subtitle<'a>>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
Source§

impl<'a> IntoIterator for Srt<'a>

Consuming iterator implementation for Srt.

This allows using Srt directly in a for loop, consuming the collection and yielding owned Subtitle values.

§Example

use skrt::Srt;

let data = "1\n00:00:00,000 --> 00:00:01,000\nHello\n\n2\n00:00:02,000 --> 00:00:03,000\nWorld\n\n";
let srt = Srt::try_parse(data).unwrap();

for subtitle in srt {
    println!("{}: {}", subtitle.seq(), subtitle.text());
}
Source§

type Item = Subtitle<'a>

The type of the elements being iterated over.
Source§

type IntoIter = IntoIter<Subtitle<'a>>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
Source§

impl<'a> PartialEq for Srt<'a>

Source§

fn eq(&self, other: &Srt<'a>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<'a> Eq for Srt<'a>

Source§

impl<'a> StructuralPartialEq for Srt<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for Srt<'a>

§

impl<'a> RefUnwindSafe for Srt<'a>

§

impl<'a> Send for Srt<'a>

§

impl<'a> Sync for Srt<'a>

§

impl<'a> Unpin for Srt<'a>

§

impl<'a> UnwindSafe for Srt<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.