SubtitleFormat

Trait SubtitleFormat 

Source
pub trait SubtitleFormat {
    // Required methods
    fn parse(&self, content: &str) -> Result<Subtitle>;
    fn serialize(&self, subtitle: &Subtitle) -> Result<String>;
    fn detect(&self, content: &str) -> bool;
    fn format_name(&self) -> &'static str;
    fn file_extensions(&self) -> &'static [&'static str];

    // Provided methods
    fn supports_styling(&self) -> bool { ... }
    fn uses_frame_timing(&self) -> bool { ... }
}
Expand description

Trait defining the interface for subtitle format parsing, serialization, and detection.

This trait provides a unified interface for working with different subtitle formats. Each format implementation provides specific parsing and serialization logic while maintaining a consistent API for format detection and conversion.

§Implementation Requirements

Implementors must provide:

  • Parsing: Convert raw text content to structured Subtitle data
  • Serialization: Convert structured data back to format-specific text
  • Detection: Identify if content belongs to this format
  • Metadata: Format name and supported file extensions

§Format Detection Priority

When multiple formats claim to support content, detection should be:

  1. Strict: Prefer specific format markers over generic patterns
  2. Fast: Use lightweight checks before expensive parsing
  3. Reliable: Minimize false positives for robust format identification

§Error Handling

All parsing and serialization methods should return crate::Result<T> to provide detailed error information about format-specific failures.

§Examples

use subx_cli::core::formats::{SubtitleFormat, Subtitle};

struct MyFormat;

impl SubtitleFormat for MyFormat {
    fn parse(&self, content: &str) -> crate::Result<Subtitle> {
        // Format-specific parsing logic
        todo!()
    }
     
    fn serialize(&self, subtitle: &Subtitle) -> crate::Result<String> {
        // Format-specific serialization logic
        todo!()
    }
     
    fn detect(&self, content: &str) -> bool {
        // Check for format-specific markers
        content.contains("my_format_marker")
    }
     
    fn format_name(&self) -> &'static str {
        "My Format"
    }
     
    fn file_extensions(&self) -> &'static [&'static str] {
        &["myf"]
    }
}

// Usage
let format = MyFormat;
let content = "...subtitle content...";

if format.detect(content) {
    let subtitle = format.parse(content)?;
    println!("Parsed {} entries", subtitle.entries.len());
}

Required Methods§

Source

fn parse(&self, content: &str) -> Result<Subtitle>

Parse subtitle content into a structured Subtitle data structure.

This method converts raw subtitle file content into the unified Subtitle representation, handling format-specific timing, text content, and styling information.

§Arguments
  • content - Raw subtitle file content as UTF-8 string
§Returns

Returns a Subtitle struct containing:

  • Parsed subtitle entries with timing and text
  • Metadata extracted from the file content
  • Format type information
§Errors

Returns an error if:

  • Content is not valid for this format
  • Timing information is malformed or invalid
  • Text encoding issues are encountered
  • Required format elements are missing
§Implementation Notes
  • Should be tolerant of minor formatting variations
  • Must validate timing consistency (start < end)
  • Should preserve as much styling information as possible
  • May apply format-specific text normalization
§Examples
let srt_content = "1\n00:00:10,500 --> 00:00:13,000\nHello World!\n\n";
let subtitle = format.parse(srt_content)?;
assert_eq!(subtitle.entries.len(), 1);
assert_eq!(subtitle.entries[0].text, "Hello World!");
Source

fn serialize(&self, subtitle: &Subtitle) -> Result<String>

Serialize a Subtitle structure into format-specific text representation.

This method converts the unified subtitle data structure back into the raw text format, applying format-specific timing, styling, and text formatting rules.

§Arguments
  • subtitle - Structured subtitle data to serialize
§Returns

Returns a formatted string that can be written to a subtitle file. The output should be valid for the target format and compatible with standard media players.

§Errors

Returns an error if:

  • Subtitle data contains invalid timing information
  • Styling information cannot be represented in the target format
  • Text content contains unsupported characters or formatting
  • Required metadata is missing for the format
§Implementation Notes
  • Should generate clean, standards-compliant output
  • Must handle timing precision appropriate for the format
  • Should gracefully degrade unsupported styling features
  • May need to validate or adjust entry ordering
§Examples
let output = format.serialize(&subtitle)?;
std::fs::write("output.srt", output)?;
Source

fn detect(&self, content: &str) -> bool

Detect whether the provided content matches this subtitle format.

This method performs lightweight content analysis to determine if the raw text content belongs to this subtitle format. It should be fast and reliable for format identification.

§Arguments
  • content - Raw subtitle file content to analyze
§Returns

Returns true if the content appears to be in this format. Should minimize false positives while catching valid content.

§Implementation Guidelines
  • Look for format-specific markers or patterns
  • Check timing format conventions
  • Validate structural elements (headers, separators)
  • Avoid expensive parsing in detection
  • Be conservative to prevent false matches
§Examples
let srt_content = "1\n00:00:10,500 --> 00:00:13,000\nText\n\n";
assert!(srt_format.detect(srt_content));

let ass_content = "[Script Info]\nTitle: Test\n[V4+ Styles]\n";
assert!(ass_format.detect(ass_content));
Source

fn format_name(&self) -> &'static str

Returns the human-readable name of this subtitle format.

This name is used for user interfaces, error messages, and format selection dialogs. It should be clear and descriptive.

§Examples
assert_eq!(srt_format.format_name(), "SubRip Text");
assert_eq!(ass_format.format_name(), "Advanced SubStation Alpha");
assert_eq!(vtt_format.format_name(), "WebVTT");
Source

fn file_extensions(&self) -> &'static [&'static str]

Returns the list of supported file extensions for this format.

Extensions should be lowercase without the leading dot. The primary extension should be listed first.

§Returns

Array of extension strings, with primary extension first.

§Examples
assert_eq!(srt_format.file_extensions(), &["srt"]);
assert_eq!(ass_format.file_extensions(), &["ass", "ssa"]);
assert_eq!(vtt_format.file_extensions(), &["vtt"]);

Provided Methods§

Source

fn supports_styling(&self) -> bool

Check if this format supports advanced styling features.

Returns true if the format can handle fonts, colors, positioning, and other advanced subtitle styling.

§Default Implementation

The default implementation returns false. Formats with styling support should override this method.

Source

fn uses_frame_timing(&self) -> bool

Check if this format uses frame-based timing.

Returns true if timing is based on frame numbers rather than absolute time, requiring frame rate information for conversion.

§Default Implementation

The default implementation returns false. Frame-based formats should override this method.

Implementors§