extendable_vm/runtime/
stack.rs1use std::fmt::{Debug, Formatter};
2use std::iter::Rev;
3use std::slice::Iter;
4
5pub 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}