#![doc = include_str!("../README.md")]
use std::{
borrow::Borrow,
hash::Hash, fmt::Debug,
};
mod trie_node;
use trie_node::TrieNode;
pub use trie_node::iter::Iter;
#[cfg(test)]
mod tests;
pub struct TrieTree<T>
{
root: TrieNode<T>,
count: usize,
}
impl<T: Hash + Eq> Eq for TrieTree<T> {}
impl<T> PartialEq for TrieTree<T>
where T: Hash + Eq
{
fn eq(&self, other: &Self) -> bool {
self.count() == other.count()
&& self.root == other.root
}
}
impl<T, I> FromIterator<I> for TrieTree<T>
where T: Hash + Eq,
I: IntoIterator<Item = T>
{
fn from_iter<IntoIter: IntoIterator<Item = I>>(iter: IntoIter) -> Self {
let mut tree = Self::new();
tree.extend(iter);
tree
}
}
impl<T, I> Extend<I> for TrieTree<T>
where T: Hash + Eq,
I: IntoIterator<Item = T>
{
fn extend<IntoIter: IntoIterator<Item = I>>(&mut self, iter: IntoIter) {
for item in iter {
self.insert(item);
}
}
}
impl<T> AsRef<Self> for TrieTree<T> {
fn as_ref(&self) -> &Self {
self
}
}
impl<T> TrieTree<T> {
pub fn count(&self) -> usize {
self.count
}
unsafe fn set_count(&mut self, value: usize) {
self.count = value
}
}
impl<T> Clone for TrieTree<T>
where T: Clone
{
fn clone(&self) -> Self {
Self {
root: self.root.clone(),
count: self.count()
}
}
}
impl<T: Debug> Debug for TrieTree<T>
where T: Hash + Eq
{
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.debug_struct("TrieTree")
.field("count", &self.count)
.field("root", &self.root)
.finish()
}
}
impl<T> Default for TrieTree<T>
where T: Hash + Eq,
{
fn default() -> Self {
Self {
root: TrieNode::default(),
count: 0,
}
}
}
impl<T> From<TrieNode<T>> for TrieTree<T>
where T: Hash + Eq,
{
fn from(mut root: TrieNode<T>) -> Self {
let mut count = 0;
root.map_nodes_last_root(&mut |node: &mut TrieNode<T>| {
if node.is_stop() {
count += 1;
}
});
Self {
root,
count
}
}
}
impl<'a, T> IntoIterator for &'a TrieTree<T>
where T: Hash + Eq
{
type Item = Vec<&'a T>;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<T> TrieTree<T>
where T: Hash + Eq
{
pub fn new() -> Self {
Self::default()
}
pub fn clear(&mut self) {
unsafe {
self.set_root(TrieNode::default());
self.set_count(0);
}
}
unsafe fn set_root(&mut self, root: TrieNode<T>) {
self.root = root
}
pub fn insert(&mut self, iter: impl IntoIterator<Item = T>) -> bool {
let res = self.root.insert(iter.into_iter());
if res {
unsafe { self.set_count(self.count() + 1) }
}
res
}
pub fn query<Q>(&self, iter: impl IntoIterator<Item = Q>) -> bool
where Q: Borrow<T>
{
self.root.query(iter.into_iter())
}
pub fn query_nostop<Q>(&self, iter: impl IntoIterator<Item = Q>) -> Option<bool>
where Q: Borrow<T>
{
self.root.query_nostop(iter.into_iter())
}
pub fn query_iter<Q>(&self, iter: impl IntoIterator<Item = Q>) -> Option<Iter<T>>
where Q: Borrow<T>
{
self.root.query_iter(iter.into_iter())
}
pub fn remove<Q>(&mut self, iter: impl IntoIterator<Item = Q>) -> bool
where Q: Borrow<T>
{
let res = self.root.remove_branch(iter.into_iter());
if res {
unsafe { self.set_count(self.count() - 1) }
}
res
}
#[allow(unused)]
unsafe fn remove_no_clean<Q>(
&mut self,
iter: impl IntoIterator<Item = Q>
) -> bool
where Q: Borrow<T>
{
let res = self.root.remove(iter.into_iter());
if res {
self.set_count(self.count() - 1)
}
res
}
pub fn iter(&self) -> Iter<T> {
self.root.iter()
}
pub fn shrink_to_fit(&mut self) {
self.root.map_nodes_first_root(&mut |node| {
node.childs_mut().shrink_to_fit()
})
}
}