use crate::TrieNode;
#[derive(Default, Debug)]
pub struct Trie(TrieNode);
impl Trie {
pub fn from(content: impl IntoIterator<Item = impl AsRef<str>>) -> Self {
let mut trie = Trie::default();
for s in content.into_iter() {
trie.insert(s.as_ref())
}
trie
}
pub fn insert(&mut self, content: &str) {
self.0.insert(content.chars().chain([STOP]))
}
pub fn iter_suffixes<'a>(&'a self, prefix: &str) -> impl Iterator<Item = String> + 'a {
let node = self.0.get_node(prefix.chars());
SuffixIterator {
child_iter: node.map(|n| n.iter_content()),
}
.filter_map(|content| content.strip_suffix(STOP).map(str::to_string))
}
pub fn iter_content<'a>(&'a self, prefix: &'a str) -> impl Iterator<Item = String> + 'a {
self.iter_suffixes(prefix)
.map(move |suffix| format!("{prefix}{suffix}"))
}
pub fn remove(&mut self, content: &str) -> Option<()> {
self.0.remove(content.chars().chain([STOP]))
}
pub fn contains_prefix(&self, prefix: &str) -> bool {
self.0.get_node(prefix.chars()).is_some()
}
pub fn contains(&self, content: &str) -> bool {
self.0.get_node(content.chars().chain([STOP])).is_some()
}
pub fn is_empty(&self) -> bool {
self.0.children.is_empty()
}
pub fn remove_suffixes(&mut self, prefix: &str) -> Option<Self> {
self.0.remove_suffixes(prefix.chars()).map(Trie)
}
}
struct SuffixIterator<'a> {
child_iter: Option<crate::node::ChildIter<'a>>,
}
impl<'a> Iterator for SuffixIterator<'a> {
type Item = String;
fn next(&mut self) -> Option<Self::Item> {
self.child_iter.as_mut()?.next()
}
}
const STOP: char = '\u{0}';
impl<S> FromIterator<S> for Trie
where
S: AsRef<str>,
{
fn from_iter<T>(string_iter: T) -> Trie
where
T: IntoIterator<Item = S>,
{
Trie::from(string_iter)
}
}