Skip to main content

ass_editor/core/history/
operation.rs

1//! Undoable operations and their memory accounting.
2//!
3//! Defines the [`Operation`] variants captured by the undo/redo system along
4//! with the delta bookkeeping required to reverse incremental script updates.
5
6use crate::core::position::{Position, Range};
7
8#[cfg(feature = "stream")]
9use ass_core::parser::ScriptDeltaOwned;
10
11#[cfg(not(feature = "std"))]
12use alloc::{string::String, vec::Vec};
13
14/// Data needed to undo a delta operation
15#[cfg(feature = "stream")]
16#[derive(Debug, Clone)]
17pub struct DeltaUndoData {
18    /// Sections that were removed (index and content)
19    pub removed_sections: Vec<(usize, String)>,
20    /// Sections that were modified (index and original content)
21    pub modified_sections: Vec<(usize, String)>,
22}
23
24/// Represents an operation that can be undone and redone
25#[derive(Debug, Clone)]
26pub enum Operation {
27    /// Text was inserted
28    Insert { position: Position, text: String },
29    /// Text was deleted
30    Delete { range: Range, deleted_text: String },
31    /// Text was replaced
32    Replace {
33        range: Range,
34        old_text: String,
35        new_text: String,
36    },
37    /// Delta was applied (for incremental updates)
38    #[cfg(feature = "stream")]
39    Delta {
40        /// The forward delta to apply
41        forward: ScriptDeltaOwned,
42        /// Data needed to undo this delta
43        undo_data: DeltaUndoData,
44    },
45}
46
47impl Operation {
48    /// Get memory usage of this operation
49    pub fn memory_usage(&self) -> usize {
50        match self {
51            Self::Insert { text, .. } => core::mem::size_of::<Self>() + text.len(),
52            Self::Delete { deleted_text, .. } => core::mem::size_of::<Self>() + deleted_text.len(),
53            Self::Replace {
54                old_text, new_text, ..
55            } => core::mem::size_of::<Self>() + old_text.len() + new_text.len(),
56            #[cfg(feature = "stream")]
57            Self::Delta { forward, undo_data } => {
58                core::mem::size_of::<Self>()
59                    + forward.added.iter().map(|s| s.len()).sum::<usize>()
60                    + forward.modified.iter().map(|(_, s)| s.len()).sum::<usize>()
61                    + undo_data
62                        .removed_sections
63                        .iter()
64                        .map(|(_, s)| s.len())
65                        .sum::<usize>()
66                    + undo_data
67                        .modified_sections
68                        .iter()
69                        .map(|(_, s)| s.len())
70                        .sum::<usize>()
71            }
72        }
73    }
74}