use super::IncrementalParser;
use crate::core::errors::EditorError;
use crate::core::{Range, Result};
use ass_core::parser::{script::ScriptDeltaOwned, Script};
#[cfg(not(feature = "std"))]
use alloc::{format, string::String, string::ToString, vec::Vec};
impl IncrementalParser {
pub fn full_reparse(&mut self, content: &str) -> Result<ScriptDeltaOwned> {
let new_script = Script::parse(content).map_err(EditorError::from)?;
let delta = if let Some(cached_content) = &self.cached_script {
let old_script = Script::parse(cached_content).map_err(EditorError::from)?;
let delta = ass_core::parser::calculate_delta(&old_script, &new_script);
let mut owned_delta = ScriptDeltaOwned {
added: Vec::new(),
modified: Vec::new(),
removed: Vec::new(),
new_issues: new_script.issues().to_vec(),
};
for section in delta.added {
owned_delta.added.push(format!("{section:?}"));
}
for (idx, section) in delta.modified {
owned_delta.modified.push((idx, format!("{section:?}")));
}
owned_delta.removed = delta.removed;
owned_delta
} else {
ScriptDeltaOwned {
added: new_script
.sections()
.iter()
.map(|s| format!("{s:?}"))
.collect(),
modified: Vec::new(),
removed: Vec::new(),
new_issues: new_script.issues().to_vec(),
}
};
self.cached_script = Some(content.to_string());
self.pending_changes.clear();
self.bytes_changed = 0;
Ok(delta)
}
pub(super) fn update_cached_script(&mut self, range: Range, new_text: &str) -> Result<()> {
if let Some(cached) = &mut self.cached_script {
if range.start.offset > cached.len() || range.end.offset > cached.len() {
return Err(EditorError::InvalidRange {
start: range.start.offset,
end: range.end.offset,
length: cached.len(),
});
}
if !cached.is_char_boundary(range.start.offset)
|| !cached.is_char_boundary(range.end.offset)
{
return Err(EditorError::command_failed(
"Cache update range is not on valid UTF-8 character boundaries",
));
}
let mut result = String::with_capacity(
cached.len() - (range.end.offset - range.start.offset) + new_text.len(),
);
result.push_str(&cached[..range.start.offset]);
result.push_str(new_text);
if range.end.offset < cached.len() {
result.push_str(&cached[range.end.offset..]);
}
*cached = result;
}
Ok(())
}
}