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}