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
Subtitledata - 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:
- Strict: Prefer specific format markers over generic patterns
- Fast: Use lightweight checks before expensive parsing
- 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§
Sourcefn parse(&self, content: &str) -> Result<Subtitle>
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!");Sourcefn serialize(&self, subtitle: &Subtitle) -> Result<String>
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)?;Sourcefn detect(&self, content: &str) -> bool
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));Sourcefn format_name(&self) -> &'static str
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");Sourcefn file_extensions(&self) -> &'static [&'static str]
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§
Sourcefn supports_styling(&self) -> bool
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.
Sourcefn uses_frame_timing(&self) -> bool
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.