graph_collections/
stack.rs

1use std::iter::FromIterator;
2
3/// A LIFO stack backed by a [`Vec`].
4///
5/// Elements are pushed and popped from the top of the stack.
6/// All operations are O(1) amortized.
7///
8/// # Examples
9/// ```
10/// use graph_collections::Stack;
11/// let mut s: Stack<i32> = Stack::new();
12/// s.push(1);
13/// s.push(2);
14/// assert_eq!(s.pop(), Some(2));
15/// assert_eq!(s.peek(), Some(&1));
16/// assert_eq!(s.len(), 1);
17/// assert!(!s.is_empty());
18/// ```
19#[derive(Debug, Clone, PartialEq)]
20pub struct Stack<T> {
21    data: Vec<T>,
22}
23
24impl<T> Default for Stack<T> {
25    fn default() -> Self {
26        Self { data: Vec::new() }
27    }
28}
29
30impl<T> From<Vec<T>> for Stack<T> {
31    fn from(data: Vec<T>) -> Self {
32        Self { data }
33    }
34}
35
36impl<T> FromIterator<T> for Stack<T> {
37    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
38        Self {
39            data: Vec::from_iter(iter),
40        }
41    }
42}
43
44/// A consuming iterator over a [`Stack`], yielding elements in LIFO order.
45pub struct IntoIter<T>(Stack<T>);
46
47impl<T> Iterator for IntoIter<T> {
48    type Item = T;
49
50    fn next(&mut self) -> Option<T> {
51        self.0.pop()
52    }
53
54    fn size_hint(&self) -> (usize, Option<usize>) {
55        let len = self.0.len();
56        (len, Some(len))
57    }
58}
59
60impl<T> ExactSizeIterator for IntoIter<T> {}
61
62impl<T> IntoIterator for Stack<T> {
63    type Item = T;
64    type IntoIter = IntoIter<T>;
65
66    fn into_iter(self) -> IntoIter<T> {
67        IntoIter(self)
68    }
69}
70
71impl<T> Stack<T> {
72    /// Creates a new empty stack.
73    ///
74    /// # Examples
75    /// ```
76    /// use graph_collections::Stack;
77    /// let s: Stack<i32> = Stack::new();
78    /// assert!(s.is_empty());
79    /// ```
80    pub fn new() -> Self {
81        Self::default()
82    }
83
84    /// Pushes a value onto the top of the stack.
85    ///
86    /// # Examples
87    /// ```
88    /// use graph_collections::Stack;
89    /// let mut s: Stack<i32> = Stack::new();
90    /// s.push(10);
91    /// assert_eq!(s.peek(), Some(&10));
92    /// ```
93    pub fn push(&mut self, value: T) {
94        self.data.push(value);
95    }
96
97    /// Removes and returns the top value, or `None` if the stack is empty.
98    ///
99    /// # Examples
100    /// ```
101    /// use graph_collections::Stack;
102    /// let mut s: Stack<i32> = Stack::new();
103    /// s.push(1);
104    /// s.push(2);
105    /// assert_eq!(s.pop(), Some(2));
106    /// assert_eq!(s.pop(), Some(1));
107    /// assert_eq!(s.pop(), None);
108    /// ```
109    pub fn pop(&mut self) -> Option<T> {
110        self.data.pop()
111    }
112
113    /// Returns a reference to the top value without removing it,
114    /// or `None` if the stack is empty.
115    ///
116    /// # Examples
117    /// ```
118    /// use graph_collections::Stack;
119    /// let mut s: Stack<i32> = Stack::new();
120    /// s.push(5);
121    /// assert_eq!(s.peek(), Some(&5));
122    /// assert_eq!(s.len(), 1); // peek does not remove
123    /// ```
124    #[must_use]
125    pub fn peek(&self) -> Option<&T> {
126        self.data.last()
127    }
128
129    /// Returns `true` if the stack contains no elements.
130    ///
131    /// # Examples
132    /// ```
133    /// use graph_collections::Stack;
134    /// let mut s: Stack<i32> = Stack::new();
135    /// assert!(s.is_empty());
136    /// s.push(1);
137    /// assert!(!s.is_empty());
138    /// ```
139    #[must_use]
140    pub fn is_empty(&self) -> bool {
141        self.data.is_empty()
142    }
143
144    /// Returns the number of elements in the stack.
145    ///
146    /// # Examples
147    /// ```
148    /// use graph_collections::Stack;
149    /// let mut s: Stack<i32> = Stack::new();
150    /// s.push(1);
151    /// s.push(2);
152    /// assert_eq!(s.len(), 2);
153    /// ```
154    #[must_use]
155    pub fn len(&self) -> usize {
156        self.data.len()
157    }
158}