ass_core/parser/script/
partial.rs1use alloc::vec::Vec;
8#[cfg(feature = "stream")]
9use alloc::{format, string::ToString};
10#[cfg(feature = "stream")]
11use core::ops::Range;
12
13use crate::parser::ast::Section;
14#[cfg(feature = "stream")]
15use crate::parser::streaming;
16#[cfg(feature = "stream")]
17use crate::Result;
18
19#[cfg(feature = "stream")]
20use super::delta::{calculate_delta, ScriptDeltaOwned};
21use super::Script;
22
23impl<'a> Script<'a> {
24 #[cfg(feature = "stream")]
43 pub fn parse_partial(&self, range: Range<usize>, new_text: &str) -> Result<ScriptDeltaOwned> {
44 let modified_source =
46 streaming::build_modified_source(self.source, range.clone(), new_text);
47
48 let change = crate::parser::incremental::TextChange {
50 range: range.clone(),
51 new_text: new_text.to_string(),
52 line_range: crate::parser::incremental::calculate_line_range(self.source, range),
53 };
54
55 let new_script = self.parse_incremental(&modified_source, &change)?;
57
58 let delta = calculate_delta(self, &new_script);
60
61 let mut owned_delta = ScriptDeltaOwned {
63 added: Vec::new(),
64 modified: Vec::new(),
65 removed: Vec::new(),
66 new_issues: Vec::new(),
67 };
68
69 for section in delta.added {
71 owned_delta.added.push(format!("{section:?}"));
72 }
73
74 for (idx, section) in delta.modified {
76 owned_delta.modified.push((idx, format!("{section:?}")));
77 }
78
79 owned_delta.removed = delta.removed;
81
82 owned_delta.new_issues = delta.new_issues;
84
85 Ok(owned_delta)
86 }
87
88 pub(super) fn adjust_section_spans(
90 section: &Section<'a>,
91 change: &crate::parser::incremental::TextChange,
92 ) -> Section<'a> {
93 use crate::parser::ast::Span;
94
95 let new_len = change.new_text.len();
97 let old_len = change.range.end - change.range.start;
98
99 let adjust_span = |span: &Span| -> Span {
101 let new_start = if new_len >= old_len {
102 span.start + (new_len - old_len)
103 } else {
104 span.start.saturating_sub(old_len - new_len)
105 };
106
107 let new_end = if new_len >= old_len {
108 span.end + (new_len - old_len)
109 } else {
110 span.end.saturating_sub(old_len - new_len)
111 };
112
113 Span::new(new_start, new_end, span.line, span.column)
114 };
115
116 match section {
118 Section::ScriptInfo(info) => {
119 let mut new_info = info.clone();
120 new_info.span = adjust_span(&info.span);
121 Section::ScriptInfo(new_info)
122 }
123 Section::Styles(styles) => {
124 let new_styles: Vec<_> = styles
125 .iter()
126 .map(|style| {
127 let mut new_style = style.clone();
128 new_style.span = adjust_span(&style.span);
129 new_style
130 })
131 .collect();
132 Section::Styles(new_styles)
133 }
134 Section::Events(events) => {
135 let new_events: Vec<_> = events
136 .iter()
137 .map(|event| {
138 let mut new_event = event.clone();
139 new_event.span = adjust_span(&event.span);
140 new_event
141 })
142 .collect();
143 Section::Events(new_events)
144 }
145 Section::Fonts(fonts) => {
146 let new_fonts: Vec<_> = fonts
147 .iter()
148 .map(|font| {
149 let mut new_font = font.clone();
150 new_font.span = adjust_span(&font.span);
151 new_font
152 })
153 .collect();
154 Section::Fonts(new_fonts)
155 }
156 Section::Graphics(graphics) => {
157 let new_graphics: Vec<_> = graphics
158 .iter()
159 .map(|graphic| {
160 let mut new_graphic = graphic.clone();
161 new_graphic.span = adjust_span(&graphic.span);
162 new_graphic
163 })
164 .collect();
165 Section::Graphics(new_graphics)
166 }
167 }
168 }
169}