use std::iter::FromIterator;
use map::{
RadixMap,
Matches as MapMatches,
Keys as MapKeys,
};
use key::Key;
pub struct RadixSet<K: Key + ?Sized> {
map: RadixMap<K, ()>,
}
impl<K: Key + ?Sized> RadixSet<K> {
pub fn new() -> RadixSet<K> {
RadixSet { map: RadixMap::new() }
}
pub fn clear(&mut self) {
self.map.clear();
}
pub fn len(&self) -> usize {
self.map.len()
}
pub fn insert(&mut self, key: &K) -> bool {
self.map.insert(key, ()).is_none()
}
pub fn contains(&self, key: &K) -> bool {
self.map.contains_key(key)
}
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
pub fn remove(&mut self, key: &K) -> bool {
self.map.remove(key).is_some()
}
pub fn iter(&self) -> Iter<K> {
self.map.keys()
}
pub fn find<'a>(&'a self, key: &K) -> Matches<'a, K> {
Matches {
iter: self.map.find(key),
}
}
}
impl<K: Key + ?Sized> Default for RadixSet<K> {
fn default() -> Self {
Self::new()
}
}
impl<K: Key + ?Sized, T: AsRef<K>> FromIterator<T> for RadixSet<K> {
fn from_iter<It>(iter: It) -> Self
where It: IntoIterator<Item=T>,
{
let iter = iter.into_iter().map(|k| (k, ()));
RadixSet { map: RadixMap::from_iter(iter), }
}
}
pub type Iter<'a, K> = MapKeys<'a, K, ()>;
pub struct Matches<'a, K: 'a + Key + ?Sized> {
iter: MapMatches<'a, K, ()>,
}
impl<'a, K: 'a + Key + ?Sized> Iterator for Matches<'a, K> {
type Item = K::Owned;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(k, _)| k)
}
}
#[cfg(test)]
mod tests {
use std::iter::FromIterator;
use super::RadixSet;
#[test]
fn it_can_be_created() {
let _: RadixSet<[i32]> = RadixSet::new();
}
#[test]
fn it_accepts_an_empty_element() {
let mut set: RadixSet<str> = RadixSet::new();
set.insert("");
assert!(!set.is_empty());
}
#[test]
fn it_accepts_an_element() {
let mut set: RadixSet<str> = RadixSet::new();
set.insert("a");
assert!(!set.is_empty());
}
#[test]
fn it_accepts_multiple_elements() {
let mut set: RadixSet<str> = RadixSet::new();
set.insert("a");
set.insert("b");
set.insert("c");
set.insert("ac");
set.insert("ab");
assert!(!set.is_empty());
}
#[test]
fn it_can_be_built_from_multiple_elements() {
let items = vec!["a", "ac", "acb", "b", "c", "d"];
let set: RadixSet<str> = items.iter().collect();
assert!(items.iter().all(|k| set.contains(k)))
}
#[test]
fn it_has_a_key_iterator() {
let mut set = RadixSet::<str>::new();
set.insert("foo");
set.insert("bar");
set.insert("baz");
let keys: Vec<_> = set.iter().collect();
assert_eq!(keys, vec!["bar", "baz", "foo"]);
}
#[test]
fn it_can_complete_keys() {
let v = vec!["foo", "bar", "baz"];
let set: RadixSet<str> = RadixSet::from_iter(v);
assert_eq!(set.find("ba").collect::<Vec<_>>(), vec!["bar", "baz"]);
}
#[test]
fn it_can_remove_keys() {
let v = vec!["foo", "bar", "baz"];
let mut set: RadixSet<str> = RadixSet::from_iter(v);
set.remove("bar");
assert!(!set.contains("bar"));
assert!(set.contains("baz"));
}
}