use std::collections::VecDeque;
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct Stack<S> {
inner: VecDeque<S>,
max_size: usize,
}
impl<S> Default for Stack<S> {
fn default() -> Self {
Self::with_max_size(usize::MAX - 1)
}
}
impl<S> FromIterator<S> for Stack<S> {
fn from_iter<T: IntoIterator<Item = S>>(iter: T) -> Self {
let mut stack = Self::default();
for item in iter {
stack.push(item);
}
stack
}
}
#[allow(dead_code)]
impl<S> Stack<S> {
pub fn new(initial_item: S) -> Self {
let mut stack = Self::default();
stack.push(initial_item);
stack
}
pub fn with_max_size(max_size: usize) -> Self {
Self {
inner: VecDeque::with_capacity(10),
max_size,
}
}
pub fn push(&mut self, value: S) -> bool {
let overflow = self.inner.len() >= self.max_size;
if overflow {
self.inner.pop_front();
}
self.inner.push_back(value);
overflow
}
pub fn pop(&mut self) -> Option<S> {
self.inner.pop_back()
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn top(&self) -> Option<&S> {
self.inner.get(self.len() - 1)
}
pub fn top_mut(&mut self) -> Option<&mut S> {
self.inner.get_mut(self.len() - 1)
}
pub fn bottom(&self) -> Option<&S> {
self.inner.front()
}
}
impl<S> Stack<S>
where
S: PartialEq,
{
pub fn contains(&self, item: &S) -> bool {
self.inner.contains(item)
}
}
#[cfg(test)]
mod test {
use crate::stack::Stack;
#[test]
fn checked_overflow() {
let mut stack = Stack::with_max_size(4);
assert!(!stack.push(1));
assert!(!stack.push(2));
assert!(!stack.push(3));
assert!(!stack.push(4));
assert!(stack.push(5));
assert!(stack.push(6));
assert!(stack.push(7));
assert_eq!(stack.len(), 4);
assert_eq!(stack.top(), Some(&7));
assert_eq!(stack.bottom(), Some(&4));
}
#[test]
fn checked_overflow_big_ass_structure() {
let high = 1_000_000;
let mut stack = Stack::with_max_size(high);
for i in 0..high + 100 {
stack.push(i);
}
assert_eq!(stack.len(), high);
}
}