pub struct Script<'a> { /* private fields */ }
Expand description
Main ASS script container with zero-copy lifetime-generic design
Uses &'a str
spans throughout the AST to avoid allocations during parsing.
Thread-safe via immutable design after construction.
Implementations§
Source§impl<'a> Script<'a>
impl<'a> Script<'a>
Sourcepub fn parse(source: &'a str) -> Result<Self>
pub fn parse(source: &'a str) -> Result<Self>
Parse ASS script from source text with zero-copy design
Performs full validation and partial error recovery. Returns script
even with errors - check issues()
for problems.
§Performance
Target <5ms for 1KB typical scripts. Uses minimal allocations via zero-copy spans referencing input text.
§Example
let script = Script::parse("[Script Info]\nTitle: Test")?;
assert_eq!(script.version(), ass_core::ScriptVersion::AssV4);
§Errors
Returns an error if the source contains malformed section headers or other unrecoverable syntax errors.
Sourcepub const fn builder() -> ScriptBuilder<'a>
pub const fn builder() -> ScriptBuilder<'a>
Create a new script builder for parsing with optional extensions
The builder pattern allows configuration of parsing options including extension registry for custom tag handlers and section processors.
§Example
let registry = ExtensionRegistry::new();
let script = Script::builder()
.with_registry(®istry)
.parse("[Script Info]\nTitle: Test")?;
let script = Script::builder()
.parse("[Script Info]\nTitle: Test")?;
Sourcepub fn parse_partial(
&self,
range: Range<usize>,
new_text: &str,
) -> Result<ScriptDeltaOwned>
pub fn parse_partial( &self, range: Range<usize>, new_text: &str, ) -> Result<ScriptDeltaOwned>
Parse incrementally with range-based updates for editors
Updates only the specified range, keeping other sections unchanged. Enables <2ms edit responsiveness for interactive editing.
§Arguments
range
- Byte range in source to re-parsenew_text
- Replacement text for the range
§Returns
Delta containing changes that can be applied to existing script.
§Errors
Returns an error if the new text contains malformed section headers or other unrecoverable syntax errors in the specified range.
Sourcepub const fn version(&self) -> ScriptVersion
pub const fn version(&self) -> ScriptVersion
Get script version detected during parsing
Sourcepub fn issues(&self) -> &[ParseIssue]
pub fn issues(&self) -> &[ParseIssue]
Get parse issues (warnings, recoverable errors)
Sourcepub fn styles_format(&self) -> Option<&[&'a str]>
pub fn styles_format(&self) -> Option<&[&'a str]>
Get format fields for [V4+ Styles] section
Sourcepub fn events_format(&self) -> Option<&[&'a str]>
pub fn events_format(&self) -> Option<&[&'a str]>
Get format fields for [Events\]
section
Sourcepub fn parse_style_line_with_context(
&self,
line: &'a str,
line_number: u32,
) -> Result<Style<'a>, ParseError>
pub fn parse_style_line_with_context( &self, line: &'a str, line_number: u32, ) -> Result<Style<'a>, ParseError>
Parse a style line with context from the script
Uses the script’s stored format for [V4+ Styles] section if available, otherwise falls back to default format.
§Arguments
line
- The style line to parse (without “Style:” prefix)line_number
- The line number for error reporting
§Returns
Parsed Style or error if the line is malformed
§Errors
Returns ParseError::InsufficientFields
if the line has fewer fields than expected
Sourcepub fn parse_event_line_with_context(
&self,
line: &'a str,
line_number: u32,
) -> Result<Event<'a>, ParseError>
pub fn parse_event_line_with_context( &self, line: &'a str, line_number: u32, ) -> Result<Event<'a>, ParseError>
Parse an event line with context from the script
Uses the script’s stored format for [Events\]
section if available,
otherwise falls back to default format.
§Arguments
line
- The event line to parse (e.g., “Dialogue: 0,0:00:00.00,0:00:05.00,Default,,0,0,0,,Text”)line_number
- The line number for error reporting
§Returns
Parsed Event or error if the line is malformed
§Errors
Returns ParseError::InvalidEventType
if the line doesn’t start with a valid event type
Returns ParseError::InsufficientFields
if the line has fewer fields than expected
Sourcepub fn parse_line_auto(
&self,
line: &'a str,
line_number: u32,
) -> Result<(SectionType, LineContent<'a>), ParseError>
pub fn parse_line_auto( &self, line: &'a str, line_number: u32, ) -> Result<(SectionType, LineContent<'a>), ParseError>
Parse a line based on its section context
Automatically determines the section type from the line content and parses accordingly.
§Arguments
line
- The line to parseline_number
- The line number for error reporting
§Returns
A tuple of (section_type
, parsed_content
) or error
§Errors
Returns error if the line format is invalid or section type cannot be determined
Sourcepub fn find_section(&self, section_type: SectionType) -> Option<&Section<'a>>
pub fn find_section(&self, section_type: SectionType) -> Option<&Section<'a>>
Find section by type
Sourcepub fn validate_spans(&self) -> bool
pub fn validate_spans(&self) -> bool
Validate all spans reference source text correctly
Debug helper to ensure zero-copy invariants are maintained.
Sourcepub fn section_range(&self, section_type: SectionType) -> Option<Range<usize>>
pub fn section_range(&self, section_type: SectionType) -> Option<Range<usize>>
Get byte range for a section
Returns the byte range (start..end) for the specified section type, or None if the section doesn’t exist or has no span.
Sourcepub fn section_at_offset(&self, offset: usize) -> Option<&Section<'a>>
pub fn section_at_offset(&self, offset: usize) -> Option<&Section<'a>>
Find section containing the given byte offset
Returns the section that contains the specified byte offset, or None if no section contains that offset.
Sourcepub fn section_boundaries(&self) -> Vec<(SectionType, Range<usize>)>
pub fn section_boundaries(&self) -> Vec<(SectionType, Range<usize>)>
Get all section boundaries for quick lookup
Returns a vector of (SectionType
, Range
) pairs for all sections
that have valid spans. Useful for building lookup tables or
determining which sections need reparsing after edits.
Sourcepub fn update_line_at_offset(
&mut self,
offset: usize,
new_line: &'a str,
line_number: u32,
) -> Result<LineContent<'a>, ParseError>
pub fn update_line_at_offset( &mut self, offset: usize, new_line: &'a str, line_number: u32, ) -> Result<LineContent<'a>, ParseError>
Update a line in the script at the given byte offset
Finds the section containing the offset and updates the appropriate line. Returns the old line content if successful.
§Arguments
offset
- Byte offset of the line to updatenew_line
- New line contentline_number
- Line number for error reporting
§Returns
The old line content if successful, or error if update failed
§Errors
Returns error if offset is invalid or line cannot be parsed
Sourcepub fn add_section(&mut self, section: Section<'a>) -> usize
pub fn add_section(&mut self, section: Section<'a>) -> usize
Sourcepub fn remove_section(
&mut self,
index: usize,
) -> Result<Section<'a>, ParseError>
pub fn remove_section( &mut self, index: usize, ) -> Result<Section<'a>, ParseError>
Sourcepub fn set_styles_format(&mut self, format: Vec<&'a str>)
pub fn set_styles_format(&mut self, format: Vec<&'a str>)
Update format for styles section
Sourcepub fn set_events_format(&mut self, format: Vec<&'a str>)
pub fn set_events_format(&mut self, format: Vec<&'a str>)
Update format for events section
Sourcepub fn batch_update_lines(
&mut self,
operations: Vec<UpdateOperation<'a>>,
) -> BatchUpdateResult<'a>
pub fn batch_update_lines( &mut self, operations: Vec<UpdateOperation<'a>>, ) -> BatchUpdateResult<'a>
Perform multiple line updates in a single operation
Updates are performed in the order provided. If an update fails, it’s recorded in the failed list but doesn’t stop other updates.
§Arguments
operations
- List of update operations to perform
§Returns
Result containing successful updates and failures
Sourcepub fn batch_add_styles(&mut self, batch: StyleBatch<'a>) -> Vec<usize>
pub fn batch_add_styles(&mut self, batch: StyleBatch<'a>) -> Vec<usize>
Sourcepub fn batch_add_events(&mut self, batch: EventBatch<'a>) -> Vec<usize>
pub fn batch_add_events(&mut self, batch: EventBatch<'a>) -> Vec<usize>
Sourcepub fn atomic_batch_update(
&mut self,
updates: Vec<UpdateOperation<'a>>,
style_additions: Option<StyleBatch<'a>>,
event_additions: Option<EventBatch<'a>>,
) -> Result<(), ParseError>
pub fn atomic_batch_update( &mut self, updates: Vec<UpdateOperation<'a>>, style_additions: Option<StyleBatch<'a>>, event_additions: Option<EventBatch<'a>>, ) -> Result<(), ParseError>
Apply a batch of mixed operations atomically
All operations are validated first. If any validation fails, no changes are made. This provides transactional semantics.
§Arguments
updates
- Line updates to performstyle_additions
- Styles to addevent_additions
- Events to add
§Returns
Ok if all operations succeed, Err with the first validation error
§Errors
Returns error if any operation would fail, without making changes
Sourcepub fn enable_change_tracking(&mut self)
pub fn enable_change_tracking(&mut self)
Enable change tracking
When enabled, all modifications to the script will be recorded in the change tracker for later analysis.
Sourcepub fn disable_change_tracking(&mut self)
pub fn disable_change_tracking(&mut self)
Disable change tracking
When disabled, modifications will not be recorded.
Sourcepub const fn is_change_tracking_enabled(&self) -> bool
pub const fn is_change_tracking_enabled(&self) -> bool
Check if change tracking is enabled
Sourcepub fn changes(&self) -> &[Change<'a>]
pub fn changes(&self) -> &[Change<'a>]
Get all recorded changes
Returns a slice of all changes recorded since tracking was enabled or since the last clear operation.
Sourcepub fn clear_changes(&mut self)
pub fn clear_changes(&mut self)
Clear all recorded changes
Removes all changes from the tracker while keeping tracking enabled/disabled.
Sourcepub fn change_count(&self) -> usize
pub fn change_count(&self) -> usize
Get the number of recorded changes
Sourcepub fn affected_sections(&self, change: &TextChange) -> Vec<SectionType>
pub fn affected_sections(&self, change: &TextChange) -> Vec<SectionType>
Sourcepub fn parse_line_in_section(
&self,
section_type: SectionType,
line: &'a str,
line_number: u32,
) -> Result<LineContent<'a>>
pub fn parse_line_in_section( &self, section_type: SectionType, line: &'a str, line_number: u32, ) -> Result<LineContent<'a>>
Parse line in section context
Parses a single line knowing its section context, using stored format information.
§Arguments
section_type
- The type of section containing this lineline
- The line text to parseline_number
- Line number for error reporting
§Returns
Parsed line content or error
§Errors
Returns ParseError::MissingFormat
if format information is missing
Returns other parse errors from line-specific parsers
Sourcepub fn parse_incremental(
&self,
new_source: &'a str,
change: &TextChange,
) -> Result<Self>
pub fn parse_incremental( &self, new_source: &'a str, change: &TextChange, ) -> Result<Self>
Parse only changed portions and create new Script
This method performs incremental parsing by identifying affected sections and reparsing only those sections while preserving others.
§Arguments
new_source
- The complete new source text after the changechange
- Description of what changed in the text
§Returns
A new Script with the changes applied
§Errors
Returns parse errors if affected sections cannot be reparsed
Sourcepub fn to_ass_string(&self) -> String
pub fn to_ass_string(&self) -> String
Convert script to ASS string representation
Generates the complete ASS script with all sections in order. Respects the stored format lines for styles and events if available.
§Examples
let script = Script::parse("[Script Info]\nTitle: Test").unwrap();
let ass_string = script.to_ass_string();
assert!(ass_string.contains("[Script Info]"));
assert!(ass_string.contains("Title: Test"));