use std::collections::HashMap;
#[derive(Debug)]
pub struct TreeItem<T> {
pub id: u32,
pub parent: Option<u32>,
pub children: Vec<u32>,
pub value: T,
}
impl<T> TreeItem<T> {
pub fn id(&self) -> u32 {
self.id
}
pub fn parent(&self) -> &Option<u32> {
&self.parent
}
pub fn children(&self) -> &Vec<u32> {
&self.children
}
pub fn unique_child(&self) -> u32 {
if let Some(id) = self.children.get(0) {
*id
} else {
panic!()
}
}
pub fn unique_child_or_none(&self) -> Option<u32> {
let len = self.children.len();
assert!(len <= 1);
self.children.get(0).cloned()
}
}
#[derive(Debug)]
pub struct Tree<T> {
items: HashMap<u32, TreeItem<T>>,
next_id: u32,
}
impl<T> Tree<T> {
pub fn new() -> Tree<T> {
Tree {
items: HashMap::new(),
next_id: 0,
}
}
pub fn clear(&mut self) {
self.items.clear();
}
pub fn create_with_parent(&mut self, parent: Option<u32>, value: T) -> u32 {
let id = self.next_id;
self.next_id += 1;
let item = TreeItem {
id: id,
parent: parent,
children: Vec::new(),
value: value,
};
self.items.insert(id, item);
if let Some(parent) = parent {
let parent_item = self.items.get_mut(&parent);
parent_item.unwrap().children.push(id);
}
id
}
pub fn create(&mut self, value: T) -> u32 {
self.create_with_parent(None, value)
}
pub fn get_item(&self, id: u32) -> &TreeItem<T> {
self.items.get(&id).unwrap()
}
fn get_item_mut(&mut self, id: u32) -> &mut TreeItem<T> {
self.items.get_mut(&id).unwrap()
}
pub fn get(&self, id: u32) -> &T {
&self.get_item(id).value
}
pub fn get_mut(&mut self, id: u32) -> &mut T {
&mut self.get_item_mut(id).value
}
pub fn child(&mut self, parent_id: u32, child_id: u32) {
let mut child = self.get_item_mut(child_id);
assert!(child.parent.is_none());
child.parent = Some(parent_id);
let parent = self.get_item_mut(parent_id);
parent.children.push(child_id);
}
pub fn children(&self, node: u32) -> &Vec<u32> {
&self.get_item(node).children
}
pub fn unique_child(&self, parent_id: u32) -> u32 {
self.get_item(parent_id).unique_child()
}
}