use super::iter::{ViewIndexIter, ViewIter};
use super::{DefaultIx, IndexType, Node, NodeIndex, Tree};
use crate::prelude::*;
#[derive(Debug)]
pub struct TreeView<'s, N: Node<Ix>, Ix: IndexType = DefaultIx> {
pub(crate) root: NodeIndex<Ix>,
pub(crate) nodes: BTreeMap<NodeIndex<Ix>, &'s N>,
}
impl<'s, N: Node<Ix>, Ix: IndexType> TreeView<'s, N, Ix> {
pub(crate) fn new(root: NodeIndex<Ix>, nodes: Vec<(NodeIndex<Ix>, &'s N)>) -> Self {
Self {
root,
nodes: nodes.iter().map(|(idx, node)| (*idx, *node)).collect(),
}
}
pub fn root(&self) -> &'s N {
self.nodes.get(&self.root).unwrap()
}
#[inline]
pub fn len(&self) -> usize {
self.nodes.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.nodes.is_empty()
}
pub fn get(&self, index: &NodeIndex<Ix>) -> Option<&'s N> {
if let Some(&node) = self.nodes.get(index) {
Some(node)
} else {
None
}
}
pub fn iter(self) -> ViewIter<'s, N, Ix> {
ViewIter::new(self)
}
pub fn iter_idx(self) -> ViewIndexIter<'s, N, Ix> {
ViewIndexIter::new(self)
}
}
impl<'source, N: Node<Ix>, Ix: IndexType> From<&'source Tree<N, Ix>> for TreeView<'source, N, Ix> {
fn from(value: &'source Tree<N, Ix>) -> Self {
let root = value.root.unwrap();
let root_node: &N = &value[root];
let mut nodes: Vec<(NodeIndex<Ix>, &'source N)> = vec![(root, root_node)];
let mut q: VecDeque<NodeIndex<Ix>> = VecDeque::from(vec![root]);
while let Some(idx) = q.pop_front() {
let node = &value[idx];
for child in node.children() {
nodes.push((child, &value[child]));
q.push_back(child);
}
}
TreeView::new(root, nodes)
}
}
impl<'s, N: Node<Ix>, Ix: IndexType> IntoIterator for TreeView<'s, N, Ix> {
type IntoIter = ViewIter<'s, N, Ix>;
type Item = &'s N;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
#[cfg(test)]
mod test {
use crate::prelude::*;
use crate::tree::node::DefaultNode as Node;
use crate::{NodeIndex, Tree};
#[test]
fn test_tree_view_construction() {
let mut root: Node<String> = Node::new("hello".to_string());
root.children = vec![NodeIndex::new(1), NodeIndex::new(2)];
let mut tree: Tree<Node<String>> = Tree::new();
tree.root = Some(NodeIndex::new(0));
tree.nodes.push(root);
tree.nodes.push(Node::new("world".to_string()));
tree.nodes.push(Node::new("!".to_string()));
let view = tree.view();
let node = view.root();
assert!(node == &tree.nodes[0])
}
}