pub(crate) mod debug;
pub(crate) mod iter;
use std::{
collections::HashMap,
borrow::Borrow,
hash::Hash
};
use crate::TrieTree;
use self::iter::Iter;
pub(crate) struct TrieNode<T> {
stop: bool,
childs: HashMap<T, Self>
}
impl<T: Hash + Eq> Eq for TrieNode<T> {}
impl<T> PartialEq for TrieNode<T>
where T: Hash + Eq
{
fn eq(&self, other: &Self) -> bool {
self.stop() == other.stop()
&& self.childs() == other.childs()
}
}
impl<T> Clone for TrieNode<T>
where T: Clone,
{
fn clone(&self) -> Self {
Self {
stop: self.stop(),
childs: self.childs().clone(),
}
}
}
impl<T> Default for TrieNode<T> {
fn default() -> Self {
Self {
stop: false,
childs: HashMap::with_capacity(0),
}
}
}
impl<T> TrieNode<T> {
#[allow(unused)]
pub fn new() -> Self {
Self::default()
}
fn set_stop(&mut self) {
self.stop = true
}
fn unset_stop(&mut self) {
self.stop = false
}
pub fn stop(&self) -> bool {
self.stop
}
pub fn is_stop(&self) -> bool {
self.stop()
}
pub fn is_empty(&self) -> bool {
self.childs.is_empty()
}
pub fn can_remove(&self) -> bool {
!self.stop() && self.is_empty()
}
pub fn childs(&self) -> &HashMap<T, Self> {
&self.childs
}
pub fn childs_mut(&mut self) -> &mut HashMap<T, Self> {
&mut self.childs
}
pub fn iter(&self) -> Iter<T> {
self.into()
}
#[allow(unused)]
pub fn map_nodes_first_root<F>(&mut self, f: &mut F)
where F: FnMut(&mut Self)
{
f(self);
self.childs_mut().values_mut().for_each(|child| {
child.map_nodes_first_root(f);
});
}
#[allow(unused)]
pub fn map_nodes_last_root<F>(&mut self, f: &mut F)
where F: FnMut(&mut Self)
{
self.childs_mut().values_mut().for_each(|child| {
child.map_nodes_last_root(f)
});
f(self);
}
#[allow(unused)]
pub fn try_map_nodes_first_root<F, E>(&mut self, f: &mut F) -> Result<(), E>
where F: FnMut(&mut Self) -> Result<(), E>
{
f(self)?;
for child in self.childs_mut().values_mut() {
child.try_map_nodes_first_root(f)?
}
Ok(())
}
#[allow(unused)]
pub fn try_map_nodes_last_root<F, E>(&mut self, f: &mut F) -> Result<(), E>
where F: FnMut(&mut Self) -> Result<(), E>
{
for child in self.childs_mut().values_mut() {
child.try_map_nodes_last_root(f)?
}
f(self)?;
Ok(())
}
}
impl<T> From<TrieTree<T>> for TrieNode<T>
where T: Hash + Eq
{
fn from(tree: TrieTree<T>) -> Self {
tree.root
}
}
impl<T> TrieNode<T>
where T: Hash + Eq
{
pub fn get_child(&self, query: impl Borrow<T>) -> Option<&Self> {
self.childs.get(query.borrow())
}
fn get_child_mut(&mut self, query: impl Borrow<T>) -> Option<&mut Self> {
self.childs.get_mut(query.borrow())
}
fn get_or_insert_child(&mut self, data: T) -> &mut Self {
self.childs.entry(data).or_default()
}
pub fn remove_child(&mut self, query: impl Borrow<T>) -> Option<Self> {
self.childs.remove(query.borrow())
}
fn removed_do<Q>(
&mut self,
mut iter: impl Iterator<Item = Q>,
cleaner: &impl Fn(&mut Self, Q),
) -> bool
where Q: Borrow<T>
{
if let Some(query) = iter.next() {
if let Some(node) = self.get_child_mut(query.borrow()) {
let is_removed = node.removed_do(iter, cleaner);
cleaner(self, query);
is_removed
} else {
false
}
} else {
let stop = self.stop();
if stop {
self.unset_stop();
} else {
}
stop
}
}
pub unsafe fn remove<Q>(&mut self, iter: impl Iterator<Item = Q>) -> bool
where Q: Borrow<T>
{
self.removed_do(iter, &|_, _| ())
}
pub fn remove_branch<Q>(&mut self, iter: impl Iterator<Item = Q>) -> bool
where Q: Borrow<T>
{
self.removed_do(iter, &|self_, query| {
if self_.get_child(query.borrow()).unwrap().can_remove() {
let res = self_.remove_child(query);
debug_assert!(matches!(res, Some(..)))
}
})
}
pub fn query<Q>(&self, iter: impl Iterator<Item = Q>) -> bool
where Q: Borrow<T>
{
debug_assert!(! bool::default());
self.query_node(iter)
.map(|node| node.is_stop())
.unwrap_or_default()
}
pub fn query_nostop<Q>(&self, iter: impl Iterator<Item = Q>) -> Option<bool>
where Q: Borrow<T>
{
self.query_node(iter).map(|node| node.is_stop())
}
pub fn query_node<Q>(&self, iter: impl Iterator<Item = Q>) -> Option<&Self>
where Q: Borrow<T>
{
let mut root = self;
for query in iter {
root = root.get_child(query)?
}
Some(root)
}
pub fn query_iter<Q>(&self, iter: impl Iterator<Item = Q>) -> Option<Iter<T>>
where Q: Borrow<T>
{
self.query_node(iter)
.map(|node| node.iter())
}
pub fn insert(&mut self, iter: impl Iterator<Item = T>) -> bool {
let mut root = self;
for data in iter {
root = root.get_or_insert_child(data)
}
if root.stop() {
false
} else {
root.set_stop();
true
}
}
}