use super::{Node, NodeValue, Trie};
impl<K, V> Trie<K, V>
where
K: Clone + Eq + std::hash::Hash + std::fmt::Debug,
V: Clone + PartialEq + std::fmt::Debug,
{
pub fn iter(&self) -> NodeIterator<K, V> {
self.into_iter()
}
}
impl<'a, K, V> IntoIterator for &'a Trie<K, V>
where
K: Clone + Eq + std::hash::Hash + std::fmt::Debug,
V: Clone + PartialEq + std::fmt::Debug,
{
type Item = <&'a Node<K, V> as IntoIterator>::Item;
type IntoIter = <&'a Node<K, V> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
Node::iter(&self.root)
}
}
#[derive(Debug)]
#[allow(clippy::module_name_repetitions)]
pub struct NodeIterator<K, V>
where
K: Clone + Eq + std::hash::Hash + std::fmt::Debug,
V: Clone + PartialEq + std::fmt::Debug,
{
children: Vec<(Vec<K>, V)>,
}
impl<K, V> NodeIterator<K, V>
where
K: Clone + Eq + std::hash::Hash + std::fmt::Debug,
V: Clone + PartialEq + std::fmt::Debug,
{
pub fn new(root: &Node<K, V>) -> Self {
let children = extract_child(vec![], root);
Self { children }
}
}
impl<K, V> Node<K, V>
where
K: Clone + Eq + std::hash::Hash + std::fmt::Debug,
V: Clone + PartialEq + std::fmt::Debug,
{
pub fn iter(&self) -> NodeIterator<K, V> {
NodeIterator::new(self)
}
}
impl<K, V> IntoIterator for &Node<K, V>
where
K: Clone + Eq + std::hash::Hash + std::fmt::Debug,
V: Clone + PartialEq + std::fmt::Debug,
{
type Item = (Vec<K>, V);
type IntoIter = NodeIterator<K, V>;
fn into_iter(self) -> Self::IntoIter {
Node::iter(self)
}
}
fn extract_child<K, V>(current_key: Vec<K>, node: &Node<K, V>) -> Vec<(Vec<K>, V)>
where
K: Clone + Eq + std::hash::Hash + std::fmt::Debug,
V: Clone + PartialEq + std::fmt::Debug,
{
match &node.value {
NodeValue::Parent { children } => children
.iter()
.flat_map(|(key, value)| {
let mut new_key = current_key.clone();
new_key.push(key.to_owned());
extract_child(new_key, value)
})
.collect(),
NodeValue::Child { value: path } => {
vec![(current_key, path.to_owned())]
}
}
}
impl<K, V> Iterator for NodeIterator<K, V>
where
K: Clone + Eq + std::hash::Hash + std::fmt::Debug,
V: Clone + PartialEq + std::fmt::Debug,
{
type Item = (Vec<K>, V);
fn next(&mut self) -> Option<Self::Item> {
self.children.pop()
}
}