1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//! Structural mutation of sections, styles, and events.
//!
//! Implements the single-item insertion and removal operations that add or
//! drop whole sections, append styles to `[V4+ Styles]`, and append events to
//! `[Events]`, creating the target section on demand.
use alloc::vec;
use crate::parser::ast::{Event, Section, Style};
use crate::parser::errors::ParseError;
use super::types::Change;
use super::Script;
impl<'a> Script<'a> {
/// Add a new section to the script
///
/// # Arguments
///
/// * `section` - The section to add
///
/// # Returns
///
/// The index of the added section
pub fn add_section(&mut self, section: Section<'a>) -> usize {
let index = self.sections.len();
self.change_tracker.record(Change::SectionAdded {
section: section.clone(),
index,
});
self.sections.push(section);
index
}
/// Remove a section by index
///
/// # Arguments
///
/// * `index` - The index of the section to remove
///
/// # Returns
///
/// The removed section if successful
///
/// # Errors
///
/// Returns error if index is out of bounds
pub fn remove_section(
&mut self,
index: usize,
) -> core::result::Result<Section<'a>, ParseError> {
if index < self.sections.len() {
let section = self.sections.remove(index);
self.change_tracker.record(Change::SectionRemoved {
section_type: section.section_type(),
index,
});
Ok(section)
} else {
Err(ParseError::IndexOutOfBounds)
}
}
/// Add a style to the [V4+ Styles] section
///
/// Creates the section if it doesn't exist.
///
/// # Arguments
///
/// * `style` - The style to add
///
/// # Returns
///
/// The index of the style within the styles section
pub fn add_style(&mut self, style: Style<'a>) -> usize {
// Find or create styles section
let styles_section_index = self
.sections
.iter()
.position(|s| matches!(s, Section::Styles(_)));
if let Some(index) = styles_section_index {
if let Section::Styles(styles) = &mut self.sections[index] {
styles.push(style);
styles.len() - 1
} else {
unreachable!("Section type mismatch");
}
} else {
// Create new styles section
self.sections.push(Section::Styles(vec![style]));
0
}
}
/// Add an event to the `[Events\]` section
///
/// Creates the section if it doesn't exist.
///
/// # Arguments
///
/// * `event` - The event to add
///
/// # Returns
///
/// The index of the event within the events section
pub fn add_event(&mut self, event: Event<'a>) -> usize {
// Find or create events section
let events_section_index = self
.sections
.iter()
.position(|s| matches!(s, Section::Events(_)));
if let Some(index) = events_section_index {
if let Section::Events(events) = &mut self.sections[index] {
events.push(event);
events.len() - 1
} else {
unreachable!("Section type mismatch");
}
} else {
// Create new events section
self.sections.push(Section::Events(vec![event]));
0
}
}
}