use std::fmt;
pub struct Trie<K, V> {
pub data: Option<V>,
pub children: Vec<(K, Trie<K, V>)>,
}
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for Trie<K, V> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Trie")
.field("data", &self.data)
.field("children", &self.children)
.finish()
}
}
impl<K: Ord + Clone, V> Trie<K, V> {
pub fn new() -> Trie<K, V> {
Trie {
data: None,
children: vec![],
}
}
pub fn add<P: IntoIterator<Item = K>>(
mut self,
path: P,
data: V,
) -> Result<Trie<K, V>, (Trie<K, V>, V)> {
let mut path = path.into_iter();
let c = path.next();
if c.is_none() {
if self.data.is_some() {
return Err((self, data));
} else {
self.data = Some(data);
return Ok(self);
}
}
let c = c.unwrap();
match self.children.binary_search_by_key(&c, |p| p.0.clone()) {
Err(i) => {
let new_child = Trie::new();
new_child.add(path, data).map(|tr| {
self.children.insert(i, (c, tr));
self
})
}
Ok(i) => {
let (_, tr) = self.children.remove(i);
tr.add(path, data).map(|tr| {
self.children.insert(i, (c, tr));
self
})
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
let t = Trie::new();
let t = t.add("foo".chars(), 42).map_err(|_| ()).unwrap();
let t = t.add("foobar".chars(), 0);
println!("{:?}", t);
assert!(t.is_ok())
}
}