use map::{Iter as MapIter, PrefixMap};
use std::hash::{Hash, Hasher};
use std::iter::{FromIterator, FusedIterator};
#[derive(Debug, Default)]
pub struct PrefixSet<T> {
map: PrefixMap<T, ()>,
}
impl<T: Eq + Clone> PrefixSet<T> {
pub fn new() -> PrefixSet<T> {
PrefixSet {
map: PrefixMap::new(),
}
}
pub fn clear(&mut self) {
self.map.clear()
}
pub fn contains<Q>(&self, key: Q) -> bool
where
Q: AsRef<[T]>,
{
self.map.get(key).is_some()
}
pub fn insert<Q>(&mut self, key: Q) -> bool
where
Q: AsRef<[T]>,
{
self.map.insert(key, ()).is_none()
}
pub fn remove<Q>(&mut self, key: Q) -> bool
where
Q: AsRef<[T]>,
{
self.map.remove(key).is_some()
}
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
pub fn len(&self) -> usize {
self.map.len()
}
pub fn iter(&self) -> Iter<T> {
Iter {
iter: self.map.iter(),
}
}
}
impl<'a, T: 'a + Eq + Clone> FromIterator<&'a [T]> for PrefixSet<T> {
fn from_iter<I>(iter: I) -> PrefixSet<T>
where
I: IntoIterator<Item = &'a [T]>,
{
let mut set = PrefixSet::new();
iter.into_iter().for_each(|x| {
set.insert(x);
});
set
}
}
impl<'a, T: 'a + Eq + Clone> IntoIterator for &'a PrefixSet<T> {
type Item = Vec<T>;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
pub struct Iter<'a, T> {
iter: MapIter<'a, T, ()>,
}
impl<'a, T: 'a + Eq + Clone> Iterator for Iter<'a, T> {
type Item = Vec<T>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(k, _)| k)
}
}
impl<'a, T: 'a + Eq + Clone> ExactSizeIterator for Iter<'a, T> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<'a, T: 'a + Eq + Clone> FusedIterator for Iter<'a, T> {}
impl<T: Eq + Clone> PartialEq<PrefixSet<T>> for PrefixSet<T> {
fn eq(&self, other: &PrefixSet<T>) -> bool {
self.len() == other.len() && self.iter().zip(other).all(|(a, b)| a == b)
}
}
impl<T: Eq + Clone> Eq for PrefixSet<T> {}
impl<T: Eq + Clone + Hash> Hash for PrefixSet<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.iter().for_each(|x| x.hash(state))
}
}