ass_editor/core/document/
incremental_parse.rs1use super::EditorDocument;
8use crate::core::errors::Result;
9use crate::core::position::Range;
10
11#[cfg(feature = "stream")]
12use crate::core::errors::EditorError;
13#[cfg(feature = "stream")]
14use crate::core::position::Position;
15#[cfg(feature = "stream")]
16use ass_core::parser::script::ScriptDeltaOwned;
17#[cfg(feature = "stream")]
18use ass_core::parser::Script;
19#[cfg(feature = "stream")]
20use core::ops::Range as StdRange;
21
22#[cfg(all(feature = "stream", not(feature = "std")))]
23use alloc::format;
24
25impl EditorDocument {
26 pub fn edit_safe(&mut self, range: Range, new_text: &str) -> Result<()> {
32 #[cfg(feature = "stream")]
33 {
34 match self.edit_incremental(range, new_text) {
36 Ok(_) => return Ok(()),
37 Err(_e) => {
38 #[cfg(feature = "std")]
39 eprintln!("Incremental edit failed, falling back to regular replace: {_e}");
40 }
41 }
42 }
43
44 self.replace(range, new_text)
46 }
47
48 #[cfg(feature = "stream")]
50 pub fn edit_event_incremental(
51 &mut self,
52 event_text: &str,
53 new_text: &str,
54 ) -> Result<ScriptDeltaOwned> {
55 let content = self.text();
56 if let Some(pos) = content.find(event_text) {
57 let range = Range::new(Position::new(pos), Position::new(pos + event_text.len()));
58 self.edit_incremental(range, new_text)
59 } else {
60 Err(EditorError::ValidationError {
61 message: format!("Event text not found: {event_text}"),
62 })
63 }
64 }
65
66 #[cfg(feature = "stream")]
68 pub fn parse_with_delta_tracking<F, R>(
69 &self,
70 range: Option<StdRange<usize>>,
71 new_text: Option<&str>,
72 f: F,
73 ) -> Result<R>
74 where
75 F: FnOnce(&Script, Option<&ScriptDeltaOwned>) -> R,
76 {
77 let content = self.text();
78 let script = Script::parse(&content).map_err(EditorError::from)?;
79
80 if let (Some(range), Some(text)) = (range, new_text) {
81 match script.parse_partial(range, text) {
83 Ok(delta) => Ok(f(&script, Some(&delta))),
84 Err(_) => {
85 Ok(f(&script, None))
87 }
88 }
89 } else {
90 Ok(f(&script, None))
91 }
92 }
93}