1use std::collections::VecDeque;
4
5pub struct SnapshotHistory<S> {
6 undo: VecDeque<S>,
7 redo: Vec<S>,
8 limit: usize,
9}
10
11impl<S> SnapshotHistory<S> {
12 pub fn new(limit: usize) -> Self {
13 Self {
14 undo: VecDeque::new(),
15 redo: Vec::new(),
16 limit,
17 }
18 }
19
20 pub fn set_limit(&mut self, limit: usize) {
21 self.limit = limit;
22 self.trim();
23 let excess = self.redo.len().saturating_sub(limit);
24 self.redo.drain(..excess);
25 }
26
27 pub fn clear(&mut self) {
28 self.undo.clear();
29 self.redo.clear();
30 }
31
32 pub fn can_undo(&self) -> bool {
33 !self.undo.is_empty()
34 }
35
36 pub fn record(&mut self, before: Option<S>) {
38 self.redo.clear();
39 if let Some(before) = before {
40 self.undo.push_back(before);
41 self.trim();
42 }
43 }
44
45 pub fn undo(&mut self, current: impl FnOnce() -> S) -> Option<S> {
46 let previous = self.undo.pop_back()?;
47 self.redo.push(current());
48 Some(previous)
49 }
50
51 pub fn redo(&mut self, current: impl FnOnce() -> S) -> Option<S> {
52 let next = self.redo.pop()?;
53 self.undo.push_back(current());
54 self.trim();
55 Some(next)
56 }
57
58 fn trim(&mut self) {
59 while self.undo.len() > self.limit {
60 self.undo.pop_front();
61 }
62 }
63}