1use collection::Collection;
2
3pub trait StackLike<T>: Collection<Item = T> {
4 fn top(&self) -> Option<&T>;
5 fn pop(&mut self) -> Option<T>;
6 fn push(&mut self, element: T);
7
8 fn fork(&self) -> Self
9 where
10 Self: Sized + Clone,
11 {
12 self.clone()
13 }
14
15 fn pushes<I>(&mut self, elements: I)
16 where
17 I: IntoIterator<Item = T>,
18 {
19 for element in elements {
20 self.push(element);
21 }
22 }
23
24 fn replace_top(&mut self, new_top: T) -> Option<T> {
25 let removed = self.pop();
26 self.push(new_top);
27 removed
28 }
29}
30
31pub trait CircularStackLike<T>: StackLike<T> {
32 type Error;
33
34 fn capacity(&self) -> usize;
35 fn at(&self, index: isize) -> Option<&T>;
36 fn update(&mut self, index: isize, element: T) -> bool;
37 fn resize(&mut self, new_capacity: usize) -> Result<(), Self::Error>;
38 fn rearrange(&mut self);
39}
40
41#[cfg(test)]
42mod tests {
43 use collection::{Collection, Disposable};
44
45 use super::StackLike;
46
47 #[derive(Default, Clone)]
48 struct TestStack {
49 disposed: bool,
50 values: Vec<i32>,
51 }
52
53 impl Disposable for TestStack {
54 fn dispose(&mut self) {
55 self.disposed = true;
56 self.values.clear();
57 }
58
59 fn is_disposed(&self) -> bool {
60 self.disposed
61 }
62 }
63
64 impl Collection for TestStack {
65 type Item = i32;
66 type Iter<'a>
67 = std::slice::Iter<'a, i32>
68 where
69 Self: 'a;
70
71 fn iter(&self) -> Self::Iter<'_> {
72 self.values.iter()
73 }
74
75 fn size(&self) -> usize {
76 self.values.len()
77 }
78
79 fn clear(&mut self) {
80 self.values.clear();
81 }
82
83 fn retain<F>(&mut self, mut f: F) -> usize
84 where
85 F: FnMut(&Self::Item) -> bool,
86 {
87 let before = self.values.len();
88 self.values.retain(|x| f(x));
89 before - self.values.len()
90 }
91 }
92
93 impl StackLike<i32> for TestStack {
94 fn top(&self) -> Option<&i32> {
95 self.values.last()
96 }
97
98 fn push(&mut self, element: i32) {
99 self.values.push(element);
100 }
101
102 fn pop(&mut self) -> Option<i32> {
103 self.values.pop()
104 }
105 }
106
107 #[test]
108 fn default_pushes_should_push_elements_in_order() {
109 let mut s = TestStack::default();
110
111 s.pushes([1, 2, 3]);
112 assert_eq!(s.values, vec![1, 2, 3]);
113 assert_eq!(s.top(), Some(&3));
114 }
115
116 #[test]
117 fn default_replace_top_should_work_for_empty_and_non_empty_stack() {
118 let mut s = TestStack::default();
119
120 assert_eq!(s.replace_top(10), None);
121 assert_eq!(s.values, vec![10]);
122 assert_eq!(s.top(), Some(&10));
123
124 assert_eq!(s.replace_top(20), Some(10));
125 assert_eq!(s.values, vec![20]);
126 assert_eq!(s.top(), Some(&20));
127 }
128
129 #[test]
130 fn default_fork_should_clone_stack_snapshot() {
131 let mut s = TestStack::default();
132 s.pushes([1, 2, 3]);
133
134 let forked = StackLike::fork(&s);
135 assert_eq!(forked.values, vec![1, 2, 3]);
136 assert_eq!(forked.top(), Some(&3));
137 }
138}