extendable_vm/runtime/
stack.rs

1use std::fmt::{Debug, Formatter};
2use std::iter::Rev;
3use std::slice::Iter;
4
5/// An abstraction that represents a stack data structure
6pub struct Stack<T> {
7    data: Vec<T>,
8}
9
10impl<T> Stack<T> {
11    pub fn empty() -> Stack<T> {
12        Stack { data: vec![] }
13    }
14
15    pub fn len(&self) -> usize {
16        self.data.len()
17    }
18
19    pub fn peek_mut(&mut self) -> Option<&mut T> {
20        self.data.last_mut()
21    }
22
23    pub fn peek(&self) -> Option<&T> {
24        self.data.last()
25    }
26
27    pub fn push(&mut self, value: T) {
28        self.data.push(value)
29    }
30
31    pub fn set(&mut self, index: usize, value: T) -> Result<(), ()> {
32        if index < self.len() {
33            self.data[index] = value;
34            Ok(())
35        } else {
36            Err(())
37        }
38    }
39
40    pub fn pop(&mut self) -> Option<T> {
41        self.data.pop()
42    }
43
44    pub fn get_from_top(&self, index_from_top: usize) -> Option<&T> {
45        if index_from_top < self.len() {
46            self.data.get(self.len() - 1 - index_from_top)
47        } else {
48            None
49        }
50    }
51
52    pub fn get(&self, index: usize) -> Option<&T> {
53        self.data.get(index)
54    }
55
56    pub fn rev(&self) -> Rev<Iter<T>> {
57        self.data.iter().rev()
58    }
59}
60
61impl<T: Debug> Debug for Stack<T> {
62    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
63        write!(f, "{:?}", self.data)
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use crate::runtime::stack::Stack;
70
71    #[test]
72    fn stack_initially_should_have_0_size() {
73        let stack: Stack<i32> = Stack::empty();
74        assert_eq!(stack.len(), 0);
75    }
76
77    #[test]
78    fn empty_stack_should_have_size_1_after_1_element_added() {
79        let mut stack: Stack<i32> = Stack::empty();
80        stack.push(1);
81        assert_eq!(stack.len(), 1);
82    }
83
84    #[test]
85    fn empty_stack_should_have_size_100_after_100_elements_added() {
86        let mut stack: Stack<i32> = Stack::empty();
87        for i in 0..100 {
88            stack.push(i);
89        }
90        assert_eq!(stack.len(), 100);
91    }
92
93    #[test]
94    fn empty_stack_should_return_none_on_pop() {
95        let mut stack: Stack<i32> = Stack::empty();
96        assert!(stack.pop().is_none());
97    }
98
99    #[test]
100    fn stack_of_size_10_should_not_change_size_after_element_is_set() {
101        let mut stack: Stack<i32> = Stack::empty();
102        for i in 0..10 {
103            stack.push(i);
104        }
105        stack.set(5, 100).unwrap();
106        assert_eq!(stack.len(), 10);
107    }
108
109    #[test]
110    fn stack_of_size_100_should_become_99_after_element_is_popped() {
111        let mut stack: Stack<i32> = Stack::empty();
112        for i in 0..100 {
113            stack.push(i);
114        }
115        stack.pop();
116        assert_eq!(stack.len(), 99);
117    }
118}