#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TwoStackAdapter<T> {
current: Vec<T>,
next: Vec<T>,
depth: usize,
}
impl<T> TwoStackAdapter<T> {
pub fn with_root(root: T) -> Self {
Self {
current: vec![root],
next: Vec::new(),
depth: 0,
}
}
pub fn push_next(&mut self, item: T) {
self.next.push(item);
}
pub fn pop(&mut self) -> Option<T> {
if self.current.is_empty() && !self.next.is_empty() {
self.next.reverse();
std::mem::swap(&mut self.current, &mut self.next);
self.depth += 1;
}
self.current.pop()
}
pub fn depth(&self) -> usize {
self.depth
}
pub fn len(&self) -> usize {
self.current.len() + self.next.len()
}
pub fn is_empty(&self) -> bool {
self.current.is_empty() && self.next.is_empty()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn adapter_preserves_next_layer_insertion_order() {
let mut frontier = TwoStackAdapter::with_root("root");
assert_eq!(frontier.pop(), Some("root"));
frontier.push_next("a");
frontier.push_next("b");
assert_eq!(frontier.depth(), 0);
assert_eq!(frontier.pop(), Some("a"));
assert_eq!(frontier.depth(), 1);
assert_eq!(frontier.pop(), Some("b"));
assert!(frontier.is_empty());
}
}