Skip to main content

rstl_stack/
traits.rs

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}