use super::TrieNode;
use std::{
collections::hash_map::Iter as HashMapIter,
fmt::Debug,
};
#[derive(Debug, Clone)]
pub struct Iter<'a, T> {
nodes: Vec<(bool, HashMapIter<'a, T, TrieNode<T>>)>,
datas: Vec<&'a T>,
}
impl<'a, T> Iter<'a, T> {
#[inline]
pub fn next_ref(&mut self) -> Option<&Vec<&'a T>> {
self.next_op(|x| x)
}
pub fn next_op<'b, R, F>(&'b mut self, f: F) -> Option<R>
where F: FnOnce(&'b Vec<&'a T>) -> R
{
let (is_stop, kvs)
= self.nodes.last_mut()?;
Some(if *is_stop {
*is_stop = false;
f(&self.datas)
} else if let Some((data, node)) = kvs.next() {
self.datas.push(data);
self.nodes.push((node.stop(), node.childs().iter()));
self.next_op(f)?
} else {
self.datas.pop()?;
self.nodes.pop()?;
self.next_op(f)?
})
}
}
impl<'a, T> Iterator for Iter<'a, T>
{
type Item = Vec<&'a T>;
fn next(&mut self) -> Option<Self::Item> {
self.next_op(|arr| arr.clone())
}
}
impl<'a, T> From<&'a TrieNode<T>> for Iter<'a, T> {
fn from(node: &'a TrieNode<T>) -> Self {
#![allow(clippy::vec_init_then_push)]
let mut nodes = Vec::new();
nodes.push((node.stop(), node.childs().iter()));
debug_assert_eq!(nodes.len(), 1);
Self {
nodes,
datas: Vec::new()
}
}
}