stack_vm/
stack.rs

1//! A simple stack.
2
3use std::fmt;
4
5/// A stack.
6///
7/// Supports only the most basic stack operations needed for the machine.
8/// Implemending using a `Vec`.
9///
10/// ```
11/// use stack_vm::Stack;
12/// let mut stack: Stack<usize> = Stack::new();
13/// assert!(stack.is_empty());
14///
15/// stack.push(13);
16/// assert!(!stack.is_empty());
17///
18/// let value = stack.pop();
19/// assert_eq!(value, 13);
20/// ```
21#[derive(Debug, Default)]
22pub struct Stack<T>(Vec<T>);
23
24impl<T: fmt::Debug> Stack<T> {
25    /// Create a new empty `Stack` and return it.
26    pub fn new() -> Stack<T> {
27        Stack(vec![])
28    }
29
30    /// Returns `true` if the stack contains no elements.
31    pub fn is_empty(&self) -> bool {
32        self.0.is_empty()
33    }
34
35    /// Push an element onto the top of the stack.
36    pub fn push(&mut self, value: T) {
37        self.0.push(value);
38    }
39
40    /// Pop the top element off the stack and return it.
41    pub fn pop(&mut self) -> T {
42        self.0.pop().expect("Unable to pop from empty stack!")
43    }
44
45    /// Take a sneaky look at the top element on the stack.
46    pub fn peek(&self) -> &T {
47        let len = self.0.len();
48        if len == 0 {
49            panic!("Cannot peek into empty stack!")
50        }
51        &self.0[len - 1]
52    }
53
54    /// Make a sneaky change to the top element on the stack.
55    pub fn peek_mut(&mut self) -> &mut T {
56        let len = self.0.len();
57        if len == 0 {
58            panic!("Cannot peek into empty stack!")
59        }
60        &mut self.0[len - 1]
61    }
62
63    pub fn as_slice(&self) -> &[T] {
64        self.0.as_slice()
65    }
66}
67
68#[cfg(test)]
69mod test {
70    use super::*;
71
72    #[test]
73    fn new() {
74        let stack: Stack<usize> = Stack::new();
75        assert!(stack.is_empty());
76    }
77
78    #[test]
79    fn push() {
80        let mut stack: Stack<usize> = Stack::new();
81        stack.push(13);
82        assert!(!stack.is_empty());
83    }
84
85    #[test]
86    fn pop() {
87        let mut stack: Stack<usize> = Stack::new();
88        stack.push(13);
89        let value = stack.pop();
90        assert_eq!(value, 13);
91    }
92
93    #[test]
94    #[should_panic(expected = "empty stack")]
95    fn empty_pop() {
96        let mut stack: Stack<usize> = Stack::new();
97        stack.pop();
98    }
99
100    #[test]
101    fn peek() {
102        let mut stack: Stack<usize> = Stack::new();
103        stack.push(13);
104        assert_eq!(*stack.peek(), 13)
105    }
106
107    #[test]
108    #[should_panic(expected = "empty stack")]
109    fn empty_peek() {
110        let stack: Stack<usize> = Stack::new();
111        stack.peek();
112    }
113}