use crate::Stack; // TODO Complete implementation impl Stack for Vec<i32> { fn init() -> Self { todo!() } fn push_val(&mut self, i: i32) { todo!() } fn top_val(&self) -> Option<&i32> { todo!() } fn pop_val(&mut self) -> Option<i32> { todo!() } fn is_empty(&self) -> bool { todo!() } } #[derive(Debug)] pub enum ListStack { Val(i32, Option<Box<ListStack>>), Nil, } use ListStack::Nil; use ListStack::Val; // Complete implementation of Stack for ListStack impl Stack for ListStack { fn init() -> Self { Nil } fn push_val(&mut self, i: i32) { match self { Val(value, other) => *self = todo!(), Nil => *self = todo!(), }; } fn top_val(&self) -> Option<&i32> { todo!() } fn pop_val(&mut self) -> Option<i32> { match self { Val(value, other) => { let popped_value = *value; match other.take() { None => *self = Nil, Some(other) => todo!(), }; todo!() } Nil => None, } } fn is_empty(&self) -> bool { todo!() } } #[cfg(test)] mod tests { use crate::stack::ListStack; use crate::Stack; use std::fmt::Debug; use std::thread::sleep; use std::time::{Duration, Instant}; #[test] fn fill_and_clear() { println! {"Testing ListStack"} fill_and_clear_impl(ListStack::init()); println! {"Testing Vec<T>"} fill_and_clear_impl(Vec::init()); } fn fill_and_clear_impl<T: Stack + Debug>(mut stack: T) { stack.push_val(1); assert_eq!(stack.top_val(), Some(&1)); stack.push_val(2); assert_eq!(stack.top_val(), Some(&2)); stack.push_val(-3); assert_eq!(stack.top_val(), Some(&-3)); println!("{:?}", stack); let mut comparison = vec![1, 2, -3]; while let Some(val) = stack.pop_val() { assert_eq!(comparison.pop().unwrap(), val); } assert!(stack.is_empty()) } const BENCHMARK_SIZE: i32 = 10_000_000; #[test] fn benchmark() { let (pushed, popped) = bench(ListStack::init()); println!( "Own implementation took {}s for push and {} for pop.", pushed, popped ); println!("Sleeping for 10 seconds."); sleep(Duration::from_secs(10)); let (pushed, popped) = bench(Vec::init()); println!( "Vec wrapper took {}s for push and {} for pop.", pushed, popped ); } fn bench<T: Stack>(mut stack: T) -> (u64, u64) { let start = Instant::now(); for i in 1..BENCHMARK_SIZE { stack.push_val(i); } println!("Pushed all elements"); let pushed = start.elapsed().as_secs(); while stack.pop_val().is_some() {} println!("Popped all elements"); let popped = start.elapsed().as_secs(); (pushed, popped) } #[test] fn test_mem() { let stack = ListStack::init(); mem_test(stack); println!("Finished memory test for ListStack"); println!("Sleeping for 10 seconds."); sleep(Duration::from_secs(10)); let stack = Vec::init(); mem_test(stack); println!("Finished memory test for Vec<T>"); } fn mem_test<T: Stack>(mut stack: T) { for i in 1..BENCHMARK_SIZE { stack.push_val(i); stack.pop_val(); } println!("Completed memory test elements"); } }