docs.rs failed to build fasrt-0.3.0
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
A blazing fast, zero-copy subtitle parser and writer for SRT, WebVTT and ASS/SSA in Rust.
Installation
[]
= "0.3"
Features
- Zero-copy, zero-allocation parsing — borrows directly from the input string
#![no_std]support (with optionalallocandstdfeatures)- Lazy iterator-based parsing — blocks are yielded on demand
- DFA-based lexing via
logosfor fast tokenization - Strongly-typed newtypes (
Hour,Minute,Second,Millisecond,Centisecond,Percentage) with compile-time validation - W3C WebVTT spec conformant — validated against Web Platform Tests
SRT
- Strict and lossy parsing modes
- Timestamps (
HH:MM:SS,mmm) - Multiline cue bodies
- Writer (
stdfeature)
WebVTT
- WEBVTT signature and header text
- Timestamps (short
MM:SS.mmmand longHH:MM:SS.mmmforms, unbounded hours) - Cue identifiers (zero-copy
&str) - Cue settings (
vertical,line,position,size,align,region) - NOTE, STYLE, REGION blocks
- Full REGION definition parsing (
id,width,lines,regionanchor,viewportanchor,scroll) - Float percentages (e.g.,
50.5%) - CRLF, CR, LF line endings
- BOM handling
- Error recovery (
-->in cue body, malformed timing lines) - Writer with round-trip fidelity (
stdfeature) - Cue text parsing — two-layer design:
CueParser: logos DFA-backed, zero-alloc token stream (no_std)CueText: W3C spec-compliant DOM tree builder withNode/TagNodetypes (alloc/std)- Tags:
<b>,<i>,<u>,<c>,<ruby>,<rt>,<v>,<lang>, with classes and annotations - W3C tree building algorithm: implied end tags,
<rt>scoping, unterminated tag handling - Full HTML5 named character reference support (2,231 entities via
phfperfect hash map) - Numeric (
 ) and hexadecimal ( ) character references - Lazy text normalization via
CueStrwithOnceCell-cached decoding and NULL (U+0000 → U+FFFD) replacement
ASS/SSA
ASS/SSA has no formal specification; the behaviour below follows the SSA v4.00 specification document together with the VSFilter/libass renderers.
- Sections (
[Script Info],[V4 Styles],[V4+ Styles],[Events],[Fonts],[Graphics], and unknown sections verbatim) - Timestamps (
H:MM:SS.cc, centiseconds, unpadded and unbounded hours) - Event rows (
Dialogue:,Comment:,Picture:,Sound:,Movie:,Command:) -
Format:-driven field order —EventFormatpresets for ASS v4+, SSA v4 and Matroska packets - The
Name(a.k.a.Actor) speaker column surfaced as first-class data -
Style:rows exposed as zero-copy fields (style rendering semantics are out of scope) -
[Fonts]/[Graphics]payload lines preserved verbatim, never mistaken for properties - Strict and lossy parsing modes
- CRLF, CR, LF line endings, and BOM handling
- Writer with round-trip fidelity (
stdfeature) - Event text parsing — two-layer design, both usable standalone:
TextParser: logos DFA-backed, zero-alloc token stream (no_std, noallocneeded)PlainText: clean-text extraction withOnceCell-cached lazy normalization, plus an allocation-freesegments()iterator- Override blocks
{…}, with libass tag boundaries: longest-match names (\fscxis not\fs+cx), spaces skipped after the backslash, and argument lists ending at the first)(\t(0,500,\frz360)stays one tag) - libass brace semantics:
{opens a block only when a}follows,\{and\}are literal-brace escapes, so cleaning never deletes text a renderer would show \N,\nand\hescapes;\p<n>drawing mode is tokenized and skipped, never interpreted as geometry- Columns a
Format:line declares under an unrecognized name are preserved through a write, not dropped
- Standalone event parsing for embedded Matroska
S_TEXT/ASStracks, which arrive one event per packet with container timing authoritative
Optional dependencies
| Feature | Default | Description |
|---|---|---|
std |
Yes | Enables std::io writer and thiserror::Error impls |
alloc |
No | Enables CueText DOM tree and entity decoding without std |
memchr |
Yes (via alloc/std) |
SIMD-accelerated fast path for entity decoding |
Benchmarks
Measured on Apple Silicon with cargo bench (Criterion).
SRT
| Benchmark | Input | Time | Throughput |
|---|---|---|---|
| Parse (strict) | 2 cues, 89 B | ~170 ns | 520 MiB/s |
| Parse (strict) | 26 KB file | ~38 µs | 661 MiB/s |
| Parse (lossy) | 332 files, ~8 MB | ~12.1 ms | 646 MiB/s |
Collect into Vec |
26 KB file | ~40 µs | 616 MiB/s |
WebVTT
| Benchmark | Input | Time | Throughput |
|---|---|---|---|
| Parse | 2 cues, 96 B | ~318 ns | 291 MiB/s |
| Parse | Settings + region + style, 354 B | ~915 ns | 387 MiB/s |
| Parse | All WPT fixtures, ~34 KB | ~113 µs | 314 MiB/s |
Collect into Vec |
Settings + region + style, 354 B | ~973 ns | 364 MiB/s |
Cue Text
| Benchmark | Input | Time | Throughput |
|---|---|---|---|
| Parse | Tags only, 166 B | ~316 ns | 552 MiB/s |
| Parse | 500 timestamps, ~11 KB | ~14.1 µs | 776 MiB/s |
Run benchmarks yourself:
License
fasrt is under the terms of both the MIT license and the
Apache License (Version 2.0).
See LICENSE-APACHE, LICENSE-MIT for details.
Copyright (c) 2026 FinDIT Studio authors.