use std::iter::FromIterator;
use tree::{
Tree,
Iter as TreeIter,
Matches as TreeMatches,
};
use key::Key;
pub struct RadixMap<K: Key + ?Sized, V> {
tree: Tree<<K as Key>::Component, V>,
}
impl<K: Key + ?Sized, V> RadixMap<K, V> {
pub fn new() -> RadixMap<K, V> {
RadixMap { tree: Tree::new() }
}
pub fn clear(&mut self) {
self.tree.clear();
}
pub fn len(&self) -> usize {
self.tree.len()
}
pub fn insert(&mut self, key: &K, value: V) -> Option<V> {
self.tree.insert(key.as_slice(), value)
}
pub fn get(&self, key: &K) -> Option<&V> {
self.tree.get(key.as_slice())
}
pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
self.tree.get_mut(key.as_slice())
}
#[inline]
pub fn contains_key(&self, key: &K) -> bool {
self.get(key).is_some()
}
pub fn is_empty(&self) -> bool {
self.tree.is_empty()
}
pub fn remove(&mut self, key: &K) -> Option<V> {
self.tree.remove(key.as_slice())
}
pub fn iter(&self) -> Iter<K, V> {
Iter {
iter: self.tree.iter(),
}
}
pub fn keys(&self) -> Keys<K, V> {
Keys {
iter: self.iter(),
}
}
pub fn values(&self) -> Values<K, V> {
Values {
iter: self.iter(),
}
}
pub fn find<'a>(&'a self, key: &K) -> Matches<'a, K, V> {
Matches {
matches: self.tree.find(key.as_slice()),
}
}
}
impl<K: Key + ?Sized, V> Default for RadixMap<K, V> {
fn default() -> Self {
Self::new()
}
}
impl<K, V, T> FromIterator<(T, V)> for RadixMap<K, V>
where K: Key + ?Sized,
T: AsRef<K>,
{
fn from_iter<It>(iter: It) -> Self
where It: IntoIterator<Item=(T, V)>,
{
let mut tree = Tree::new();
for (t, v) in iter {
tree.insert(t.as_ref().as_slice(), v);
}
RadixMap { tree }
}
}
pub struct Iter<'a, K: 'a + Key + ?Sized, V: 'a> {
iter: TreeIter<'a, K::Component, V>,
}
impl<'a, K: 'a + Key + ?Sized, V: 'a> Iterator for Iter<'a, K, V> {
type Item = (K::Owned, &'a V);
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(k, v)| (K::from_vec(k), v))
}
}
pub struct Keys<'a, K: 'a + Key + ?Sized, V: 'a> {
iter: Iter<'a, K, V>,
}
impl<'a, K: 'a + Key + ?Sized, V: 'a> Iterator for Keys<'a, K, V> {
type Item = K::Owned;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(k, _)| k)
}
}
pub struct Values<'a, K: 'a + Key + ?Sized, V: 'a> {
iter: Iter<'a, K, V>,
}
impl<'a, K: 'a + Key + ?Sized, V: 'a> Iterator for Values<'a, K, V> {
type Item = &'a V;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(_, v)| v)
}
}
pub struct Matches<'a, K: 'a + Key + ?Sized, V: 'a> {
matches: TreeMatches<'a, K::Component, V>,
}
impl<'a, K: 'a + Key + ?Sized, V: 'a> Iterator for Matches<'a, K, V> {
type Item = (K::Owned, &'a V);
fn next(&mut self) -> Option<Self::Item> {
self.matches.next().map(|(k, v)| (K::from_vec(k), v))
}
}
#[cfg(test)]
mod tests {
use super::RadixMap;
#[test]
fn it_can_lookup_elements() {
let mut map: RadixMap<str, i32> = RadixMap::new();
map.insert("a", 0);
map.insert("ac", 1);
let v = map.get("a");
assert_eq!(v.map(|x| *x), Some(0));
let v = map.get("ac");
assert_eq!(v.map(|x| *x), Some(1));
}
#[test]
fn it_has_a_key_iterator() {
let mut map: RadixMap<str, ()> = RadixMap::new();
map.insert("foo", ());
map.insert("bar", ());
map.insert("baz", ());
let keys: Vec<_> = map.keys().collect();
assert_eq!(keys, vec!["bar", "baz", "foo"]);
}
#[test]
fn it_has_a_value_iterator() {
let mut map: RadixMap<str, i32> = RadixMap::new();
map.insert("foo", 0);
map.insert("bar", 1);
map.insert("baz", 2);
let values: Vec<_> = map.values().collect();
assert_eq!(values, vec![&1, &2, &0]);
}
}