compile_regex/utils/
stack.rs1use core::{fmt, slice};
4
5#[derive(Debug)]
6pub(crate) struct PushError;
7
8pub struct Stack<T, const N: usize = 128> {
11 inner: [T; N],
12 len: usize,
13}
14
15impl<T: fmt::Debug, const N: usize> fmt::Debug for Stack<T, N> {
16 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
17 fmt::Debug::fmt(self.as_slice(), formatter)
18 }
19}
20
21impl<T: Copy, const N: usize> Stack<T, N> {
22 pub(crate) const fn new(filler: T) -> Self {
23 Self {
24 inner: [filler; N],
25 len: 0,
26 }
27 }
28
29 pub(crate) const fn push(&mut self, item: T) -> Result<(), PushError> {
30 if self.len == N {
31 Err(PushError)
32 } else {
33 self.inner[self.len] = item;
34 self.len += 1;
35 Ok(())
36 }
37 }
38
39 pub(crate) const fn pop(&mut self) -> Option<T> {
40 if self.len == 0 {
41 None
42 } else {
43 self.len -= 1;
44 Some(self.inner[self.len])
45 }
46 }
47}
48
49impl<T, const N: usize> Stack<T, N> {
50 pub const fn as_slice(&self) -> &[T] {
52 let (start, _) = self.inner.split_at(self.len);
53 start
54 }
55
56 pub fn iter(&self) -> impl ExactSizeIterator<Item = &T> + DoubleEndedIterator + '_ {
58 self.as_slice().iter()
59 }
60
61 pub const fn is_empty(&self) -> bool {
63 self.len == 0
64 }
65
66 pub const fn len(&self) -> usize {
68 self.len
69 }
70
71 pub(crate) const fn trim(&mut self, new_len: usize) {
72 self.len = new_len;
73 }
74
75 pub(crate) const fn index_mut(&mut self, idx: usize) -> &mut T {
76 assert!(idx < self.len, "index out of range");
77 &mut self.inner[idx]
78 }
79}
80
81impl<T, const N: usize> AsRef<[T]> for Stack<T, N> {
82 fn as_ref(&self) -> &[T] {
83 self.as_slice()
84 }
85}
86
87impl<T: PartialEq, const N: usize> PartialEq for Stack<T, N> {
88 fn eq(&self, other: &Self) -> bool {
89 self.as_slice() == other.as_slice()
90 }
91}
92
93impl<'a, T, const N: usize> IntoIterator for &'a Stack<T, N> {
94 type Item = &'a T;
95 type IntoIter = slice::Iter<'a, T>;
96
97 fn into_iter(self) -> Self::IntoIter {
98 self.as_slice().iter()
99 }
100}