use core::{fmt::Debug, iter::FusedIterator};
use crate::{
storage::{Storage, DefaultStorage},
NodeValue,
};
use super::{FreeformTree, Node, NodeData};
#[derive(Debug)]
pub struct NodeRef<'a, B, L = B, K = usize, S = DefaultStorage<Node<B, L, K>>>
where
S: Storage<Element = Node<B, L, K>, Key = K>,
K: Clone + Debug + Eq,
{
pub(super) tree: &'a FreeformTree<B, L, K, S>,
pub(super) key: K,
}
impl<'a, B, L, K, S> NodeRef<'a, B, L, K, S>
where
S: Storage<Element = Node<B, L, K>, Key = K>,
K: Clone + Debug + Eq,
{
pub fn new_raw(tree: &'a FreeformTree<B, L, K, S>, key: K) -> Option<Self> {
if tree.storage.contains_key(&key) {
Some(unsafe {
Self::new_raw_unchecked(tree, key)
})
} else {
None
}
}
pub unsafe fn new_raw_unchecked(tree: &'a FreeformTree<B, L, K, S>, key: K) -> Self {
Self { tree, key }
}
pub fn raw_key(&self) -> &K {
&self.key
}
pub fn into_raw_key(self) -> K {
self.key
}
pub fn parent(&self) -> Option<Self> {
self.node().parent.as_ref().map(|x| unsafe {
Self::new_raw_unchecked(self.tree, x.clone())
})
}
pub fn prev_sibling(&self) -> Option<Self> {
self.node().prev_sibling.as_ref().map(|x| unsafe {
Self::new_raw_unchecked(self.tree, x.clone())
})
}
pub fn next_sibling(&self) -> Option<Self> {
self.node().next_sibling.as_ref().map(|x| unsafe {
Self::new_raw_unchecked(self.tree, x.clone())
})
}
pub fn first_child(&self) -> Option<Self> {
if let NodeData::Branch { first_child, .. } = &self.node().value {
unsafe {
Some(Self::new_raw_unchecked(self.tree, first_child.clone()))
}
} else {
None
}
}
pub fn last_child(&self) -> Option<Self> {
if let NodeData::Branch { last_child, .. } = &self.node().value {
unsafe {
Some(Self::new_raw_unchecked(self.tree, last_child.clone()))
}
} else {
None
}
}
#[allow(clippy::missing_const_for_fn)]
pub fn is_root(&self) -> bool {
self.node().parent.is_none()
}
pub fn is_leaf(&self) -> bool {
match &self.node().value {
NodeData::Branch { .. } => false,
NodeData::Leaf(..) => true,
}
}
pub fn is_branch(&self) -> bool {
match &self.node().value {
NodeData::Branch { .. } => true,
NodeData::Leaf(..) => false,
}
}
pub fn value(&self) -> NodeValue<&'a B, &'a L> {
self.node().value.as_ref().into_value()
}
pub fn children(&self) -> Option<NodeChildrenIter<'_, B, L, K, S>> {
self.first_child().map(Self::siblings)
}
pub fn children_keys(&self) -> Option<NodeChildKeysIter<'_, B, L, K, S>> {
self.first_child().map(Self::sibling_keys)
}
pub fn siblings(self) -> NodeSiblingsIter<'a, B, L, K, S> {
NodeSiblingsIter(self.sibling_keys())
}
pub fn sibling_keys(self) -> NodeSiblingKeysIter<'a, B, L, K, S> {
NodeSiblingKeysIter {
tree: self.tree,
key: Some(self.key),
}
}
pub(super) fn node(&self) -> &'a Node<B, L, K> {
debug_assert!(
self.tree.storage.contains_key(&self.key),
"\
debug key check failed: tried to reference key {:?} which is not present in the storage",
&self.key,
);
unsafe {
self.tree.storage.get_unchecked(&self.key)
}
}
}
impl<B, L, K, S> Copy for NodeRef<'_, B, L, K, S>
where
S: Storage<Element = Node<B, L, K>, Key = K>,
K: Copy + Debug + Eq,
{
}
impl<B, L, K, S> Clone for NodeRef<'_, B, L, K, S>
where
S: Storage<Element = Node<B, L, K>, Key = K>,
K: Clone + Debug + Eq,
{
fn clone(&self) -> Self {
Self {
tree: self.tree,
key: self.key.clone(),
}
}
}
impl<'a, B, L, K, S> From<NodeRef<'a, B, L, K, S>> for NodeValue<&'a B, &'a L>
where
S: Storage<Element = Node<B, L, K>, Key = K>,
K: Clone + Debug + Eq,
{
fn from(op: NodeRef<'a, B, L, K, S>) -> Self {
op.value()
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct NodeSiblingKeysIter<'a, B, L = B, K = usize, S = DefaultStorage<Node<B, L, K>>>
where
S: Storage<Element = Node<B, L, K>, Key = K>,
K: Clone + Debug + Eq,
{
pub(super) tree: &'a FreeformTree<B, L, K, S>,
pub(super) key: Option<K>,
}
pub type NodeChildKeysIter<'a, B, L = B, K = usize, S = DefaultStorage<Node<B, L, K>>> =
NodeSiblingKeysIter<'a, B, L, K, S>;
impl<'a, B, L, K, S> Iterator for NodeSiblingKeysIter<'a, B, L, K, S>
where
S: Storage<Element = Node<B, L, K>, Key = K>,
K: Clone + Debug + Eq,
{
type Item = K;
fn next(&mut self) -> Option<Self::Item> {
let current_key = self.key.take()?;
let next_key = unsafe {
NodeRef::new_raw_unchecked(self.tree, current_key.clone())
.next_sibling()
.map(NodeRef::into_raw_key)
};
self.key = next_key;
Some(current_key)
}
fn size_hint(&self) -> (usize, Option<usize>) {
if self.key.is_some() {
(1, None)
} else {
(0, Some(0))
}
}
}
impl<B, L, K, S> FusedIterator for NodeSiblingKeysIter<'_, B, L, K, S>
where
S: Storage<Element = Node<B, L, K>, Key = K>,
K: Clone + Debug + Eq,
{
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct NodeSiblingsIter<'a, B, L = B, K = usize, S = DefaultStorage<Node<B, L, K>>>(
pub(super) NodeSiblingKeysIter<'a, B, L, K, S>,
)
where
S: Storage<Element = Node<B, L, K>, Key = K>,
K: Clone + Debug + Eq;
pub type NodeChildrenIter<'a, B, L = B, K = usize, S = DefaultStorage<Node<B, L, K>>> =
NodeSiblingsIter<'a, B, L, K, S>;
impl<'a, B, L, K, S> Iterator for NodeSiblingsIter<'a, B, L, K, S>
where
S: Storage<Element = Node<B, L, K>, Key = K>,
K: Clone + Debug + Eq,
{
type Item = NodeRef<'a, B, L, K, S>;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|key| unsafe {
NodeRef::new_raw_unchecked(self.0.tree, key)
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
impl<B, L, K, S> FusedIterator for NodeSiblingsIter<'_, B, L, K, S>
where
S: Storage<Element = Node<B, L, K>, Key = K>,
K: Clone + Debug + Eq,
{
}