use std::fmt::Debug; pub trait VarStack : Debug { type Item; fn top(&self) -> Option<&Self::Item>; fn pop(&mut self) -> Option; fn pop_many(&mut self, count: usize) -> Option>; fn push(&mut self, value: Self::Item); fn pop_all_and_get_n_last(&mut self, nb: usize) -> Option>; fn pop_n_pairs(&mut self, nb: usize) -> Option>; fn peek(&self, nb: usize) -> Option>; } #[derive(Debug)] pub struct VectorVarStack { vector: Vec } impl VectorVarStack { pub fn new() -> VectorVarStack { VectorVarStack { vector: Vec::new() } } } impl VectorVarStack { pub fn iter(&self) -> ::std::slice::Iter { self.vector.iter() } } impl VarStack for VectorVarStack where Item: Debug { type Item = Item; fn top(&self) -> Option<&Self::Item> { self.vector.last() } fn pop(&mut self) -> Option { self.vector.pop() } fn pop_many(&mut self, count: usize) -> Option> { if count > self.vector.len() { None } else { let length = self.vector.len(); Some(self.vector.drain((length-count)..length).into_iter().collect()) } } fn push(&mut self, value: Self::Item) { self.vector.push(value) } fn pop_all_and_get_n_last(&mut self, nb: usize) -> Option> { if self.vector.len() < nb { None } else { self.vector.truncate(nb); Some(self.vector.drain(..).collect()) } } fn pop_n_pairs(&mut self, nb: usize) -> Option> { self.pop_many(nb*2).map(|values| { let mut pairs = Vec::<(Self::Item, Self::Item)>::new(); pairs.reserve(nb); for chunk in values.chunks(2) { assert!(chunk.len() == 2); // TODO: remove clones. http://stackoverflow.com/q/37097395/539465 pairs.push((chunk.get(0).unwrap().clone(), chunk.get(1).unwrap().clone())); } pairs }) } fn peek(&self, nb: usize) -> Option> { if nb > self.vector.len() { None } else { let length = self.vector.len(); Some(self.vector[(length-nb)..length].iter().collect()) } } }