excel_cli/actions/
history.rs

1use super::ActionCommand;
2use std::rc::Rc;
3
4pub struct UndoHistory {
5    undo_stack: Vec<Rc<ActionCommand>>,
6    redo_stack: Vec<Rc<ActionCommand>>,
7}
8
9impl Default for UndoHistory {
10    fn default() -> Self {
11        Self::new()
12    }
13}
14
15impl UndoHistory {
16    #[must_use]
17    pub fn new() -> Self {
18        Self {
19            undo_stack: Vec::with_capacity(100), // Pre-allocate capacity
20            redo_stack: Vec::with_capacity(20),
21        }
22    }
23
24    pub fn push(&mut self, action: ActionCommand) {
25        // Use Rc to avoid deep cloning the entire action
26        self.undo_stack.push(Rc::new(action));
27        self.redo_stack.clear();
28    }
29
30    pub fn undo(&mut self) -> Option<Rc<ActionCommand>> {
31        if let Some(action) = self.undo_stack.pop() {
32            self.redo_stack.push(Rc::clone(&action));
33            Some(action)
34        } else {
35            None
36        }
37    }
38
39    pub fn redo(&mut self) -> Option<Rc<ActionCommand>> {
40        if let Some(action) = self.redo_stack.pop() {
41            self.undo_stack.push(Rc::clone(&action));
42            Some(action)
43        } else {
44            None
45        }
46    }
47
48    #[must_use]
49    pub fn all_undone(&self) -> bool {
50        self.undo_stack.is_empty()
51    }
52
53    pub fn clear(&mut self) {
54        self.undo_stack.clear();
55        self.redo_stack.clear();
56    }
57}