1#[derive(Debug, Clone, Default)]
6pub struct UndoStack<S> {
7 stack: Vec<S>,
8}
9
10impl<S: Clone> UndoStack<S> {
11 pub fn new() -> Self {
12 Self { stack: Vec::new() }
13 }
14
15 pub fn push(&mut self, state: &S) {
17 self.stack.push(state.clone());
18 }
19
20 pub fn pop(&mut self) -> Option<S> {
22 self.stack.pop()
23 }
24
25 pub fn clear(&mut self) {
27 self.stack.clear();
28 }
29
30 pub fn len(&self) -> usize {
31 self.stack.len()
32 }
33
34 pub fn is_empty(&self) -> bool {
35 self.stack.is_empty()
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42
43 #[test]
44 fn test_push_and_pop() {
45 let mut stack = UndoStack::new();
46 stack.push(&"hello".to_string());
47 stack.push(&"world".to_string());
48 assert_eq!(stack.len(), 2);
49 assert_eq!(stack.pop(), Some("world".to_string()));
50 assert_eq!(stack.pop(), Some("hello".to_string()));
51 assert_eq!(stack.pop(), None);
52 }
53
54 #[test]
55 fn test_clear() {
56 let mut stack = UndoStack::new();
57 stack.push(&1);
58 stack.push(&2);
59 assert_eq!(stack.len(), 2);
60 stack.clear();
61 assert!(stack.is_empty());
62 }
63
64 #[test]
65 fn test_clone_semantics() {
66 let mut stack = UndoStack::new();
67 let original = "data".to_string();
68 stack.push(&original);
69 drop(original);
71 assert_eq!(stack.pop(), Some("data".to_string()));
72 }
73}