dsa/data_structures/stack.rs
1/// A stack data structure.
2///
3/// This structure implements a simple stack where elements of type `T` are pushed and popped
4/// according to the Last-In-First-Out (LIFO) principle. The stack has a fixed size of 100 elements.
5pub struct Stack<T> {
6 /// An array to store the elements of the stack.
7 ///
8 /// The stack can hold up to 100 elements of type `T`. Each element is wrapped in an `Option`
9 /// to handle the possibility of uninitialized slots (i.e., `None`).
10 ///
11 /// The array has a fixed size of 100 elements, providing the stack with a predefined capacity.
12 data: [Option<T>; 100],
13
14 /// The index of the top element in the stack.
15 ///
16 /// This value indicates the position of the last pushed element in the `data` array.
17 ///
18 /// A value of `-1` means the stack is empty, and as elements are pushed, this index
19 /// is incremented. Conversely, when elements are popped, the index is decremented.
20 top: isize,
21}
22
23impl<T> Stack<T> {
24 /// Creates a new, empty `Stack`.
25 ///
26 /// # Examples
27 ///
28 /// ```
29 /// use dsa::data_structures::stack::Stack;
30 /// let stack: Stack<i32> = Stack::new();
31 /// assert!(stack.is_empty());
32 /// ```
33 pub fn new() -> Self {
34 Stack {
35 data: [(); 100].map(|_| None),
36 top: -1,
37 }
38 }
39
40 /// Pushes a value onto the `Stack`.
41 ///
42 /// ### Examples
43 /// ```
44 /// use dsa::data_structures::stack::Stack;
45 /// let mut stack = Stack::new();
46 /// stack.push(10).unwrap();
47 /// stack.push(20).unwrap();
48 /// assert_eq!(stack.peek(), Some(&20));
49 /// assert_eq!(stack.size(), 2);
50 /// ```
51 ///
52 /// ### Parameters
53 /// - `value`: A `T` generic value that will
54 /// be pushed onto the top of this `Stack`
55 ///
56 /// ### Returns
57 /// - A `Result` object that return an `Err` if
58 /// this `Stack` is full, otherwise an empty `Ok(())`
59 pub fn push(&mut self, value: T) -> Result<(), &str> {
60 if self.top + 1 >= self.data.len() as isize {
61 Err("Stack Overflow")
62 } else {
63 self.top += 1;
64 self.data[self.top as usize] = Some(value);
65 Ok(())
66 }
67 }
68
69 /// Pops a value from the `Stack`.
70 ///
71 /// ### Examples
72 /// ```
73 /// use dsa::data_structures::stack::Stack;
74 /// let mut stack: Stack<i32> = Stack::new();
75 /// stack.push(10).unwrap();
76 /// stack.push(20).unwrap();
77 /// stack.pop();
78 /// assert_eq!(stack.pop(), Some(10));
79 /// ```
80 ///
81 /// ### Returns
82 /// - An optional `T` generic that represents the
83 /// topmost value that has been removed from this `Stack`
84 pub fn pop(&mut self) -> Option<T> {
85 if self.top == -1 {
86 None
87 } else {
88 let value = self.data[self.top as usize].take();
89 self.top -= 1;
90 value
91 }
92 }
93
94 /// Returns a reference to the top element without removing it.
95 ///
96 /// ### Examples
97 /// ```
98 /// use dsa::data_structures::stack::Stack;
99 /// let mut stack: Stack<i32> = Stack::new();
100 /// stack.push(10).unwrap();
101 /// stack.push(20).unwrap();
102 /// stack.pop();
103 /// assert_eq!(stack.peek(), Some(&10));
104 /// ```
105 ///
106 /// ### Returns
107 /// - The topmost value of this `Stack` as an optional
108 /// `T` generic reference
109 pub fn peek(&self) -> Option<&T> {
110 if self.top == -1 {
111 None
112 } else {
113 self.data[self.top as usize].as_ref()
114 }
115 }
116
117 /// Checks if the `Stack` is empty.
118 ///
119 /// ### Examples
120 /// ```
121 /// use dsa::data_structures::stack::Stack;
122 ///
123 /// let mut stack: Stack<u32> = Stack::new();
124 /// assert!(stack.is_empty());
125 /// ```
126 ///
127 /// ### Returns
128 /// - A bool value determining whether this `Stack` is empty
129 pub fn is_empty(&self) -> bool {
130 self.top == -1
131 }
132
133 /// Get the size of this `Stack`
134 ///
135 /// ### Examples
136 /// ```
137 /// use dsa::data_structures::stack::Stack;
138 /// let mut stack: Stack<i32> = Stack::new();
139 /// stack.push(10).unwrap();
140 /// stack.push(20).unwrap();
141 /// stack.pop();
142 /// assert_eq!(stack.size(), 1);
143 /// ```
144 ///
145 /// ### Returns
146 /// - An unsigned CPU architecture int representing the size of this `Stack`
147 pub fn size(&self) -> isize { self.top + 1 }
148}