107 lines
2.1 KiB
Rust
Raw Normal View History

pub trait Stackable {
2019-09-19 23:05:17 +02:00
type Item;
2019-09-19 23:05:17 +02:00
fn is_empty(&self) -> bool;
fn as_slice(&self) -> &[Self::Item];
fn push(&mut self, item: Self::Item);
fn pop1(&mut self) -> Option<Self::Item>;
fn pop(&mut self, n: usize) -> Option<Vec<Self::Item>>;
}
#[derive(Debug, Default)]
pub struct Stack<T>
where
T: Default,
{
2019-09-19 23:05:17 +02:00
inner: Vec<T>,
}
impl<T> Stack<T>
where
T: Default,
{
2019-09-19 23:05:17 +02:00
pub fn new() -> Self {
Self {
..Default::default()
}
}
2019-09-19 23:05:17 +02:00
}
impl<T> Stackable for Stack<T>
where
T: Default,
{
2019-09-19 23:05:17 +02:00
type Item = T;
2019-09-19 23:05:17 +02:00
fn is_empty(&self) -> bool {
self.inner.is_empty()
}
2019-09-19 23:05:17 +02:00
fn as_slice(&self) -> &[Self::Item] {
self.inner.as_slice()
}
fn push(&mut self, item: Self::Item) {
self.inner.push(item);
}
2019-09-19 23:05:17 +02:00
fn pop1(&mut self) -> Option<Self::Item> {
self.inner.pop()
}
2019-09-19 23:05:17 +02:00
fn pop(&mut self, n: usize) -> Option<Vec<Self::Item>> {
if self.inner.len() < n {
None
} else {
let items = self
.inner
.drain(self.inner.len() - n..)
.rev()
.collect::<Vec<Self::Item>>();
assert!(items.len() == n);
Some(items)
}
}
}
#[cfg(test)]
mod tests {
2019-09-19 23:05:17 +02:00
use super::{Stack, Stackable};
#[test]
fn test_is_empty() {
let mut stack = Stack::new();
assert_eq!(stack.is_empty(), true);
stack.push(1);
assert_eq!(stack.is_empty(), false);
}
#[test]
2019-09-19 23:05:17 +02:00
fn test_push_pop1() {
let mut stack = Stack::new();
stack.push(1);
2019-09-19 23:05:17 +02:00
assert_eq!(stack.pop1(), Some(1));
assert_eq!(stack.is_empty(), true);
}
#[test]
2019-09-19 23:05:17 +02:00
fn test_pop() {
let mut stack = Stack::new();
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.push(5);
stack.push(6);
2019-09-19 23:05:17 +02:00
assert_eq!(stack.pop(1), Some(vec![6]));
assert_eq!(stack.pop(2), Some(vec![5, 4]));
assert_eq!(stack.pop(3), Some(vec![3, 2, 1]));
assert_eq!(stack.is_empty(), true);
}
}