ass_editor/core/incremental/
reparse.rs1use super::IncrementalParser;
8use crate::core::errors::EditorError;
9use crate::core::{Range, Result};
10use ass_core::parser::{script::ScriptDeltaOwned, Script};
11
12#[cfg(not(feature = "std"))]
13use alloc::{format, string::String, string::ToString, vec::Vec};
14
15impl IncrementalParser {
16 pub fn full_reparse(&mut self, content: &str) -> Result<ScriptDeltaOwned> {
18 let new_script = Script::parse(content).map_err(EditorError::from)?;
20
21 let delta = if let Some(cached_content) = &self.cached_script {
23 let old_script = Script::parse(cached_content).map_err(EditorError::from)?;
24
25 let delta = ass_core::parser::calculate_delta(&old_script, &new_script);
27
28 let mut owned_delta = ScriptDeltaOwned {
30 added: Vec::new(),
31 modified: Vec::new(),
32 removed: Vec::new(),
33 new_issues: new_script.issues().to_vec(),
34 };
35
36 for section in delta.added {
38 owned_delta.added.push(format!("{section:?}"));
39 }
40
41 for (idx, section) in delta.modified {
43 owned_delta.modified.push((idx, format!("{section:?}")));
44 }
45
46 owned_delta.removed = delta.removed;
48
49 owned_delta
50 } else {
51 ScriptDeltaOwned {
53 added: new_script
54 .sections()
55 .iter()
56 .map(|s| format!("{s:?}"))
57 .collect(),
58 modified: Vec::new(),
59 removed: Vec::new(),
60 new_issues: new_script.issues().to_vec(),
61 }
62 };
63
64 self.cached_script = Some(content.to_string());
66 self.pending_changes.clear();
67 self.bytes_changed = 0;
68
69 Ok(delta)
70 }
71
72 pub(super) fn update_cached_script(&mut self, range: Range, new_text: &str) -> Result<()> {
74 if let Some(cached) = &mut self.cached_script {
75 if range.start.offset > cached.len() || range.end.offset > cached.len() {
77 return Err(EditorError::InvalidRange {
78 start: range.start.offset,
79 end: range.end.offset,
80 length: cached.len(),
81 });
82 }
83
84 if !cached.is_char_boundary(range.start.offset)
86 || !cached.is_char_boundary(range.end.offset)
87 {
88 return Err(EditorError::command_failed(
89 "Cache update range is not on valid UTF-8 character boundaries",
90 ));
91 }
92
93 let mut result = String::with_capacity(
95 cached.len() - (range.end.offset - range.start.offset) + new_text.len(),
96 );
97
98 result.push_str(&cached[..range.start.offset]);
100
101 result.push_str(new_text);
103
104 if range.end.offset < cached.len() {
106 result.push_str(&cached[range.end.offset..]);
107 }
108
109 *cached = result;
110 }
111
112 Ok(())
113 }
114}