eightfold 0.1.0

3D space partitioning library
Documentation
use crate::{error::Error, Octree, Proxy, ProxyData};
use std::{
    marker::PhantomData,
    ops::{Deref, DerefMut},
};

#[derive(Debug, Copy, Clone)]
pub struct View<'tree, Tree: 'tree> {
    tree: Tree,
    target: u32,
    _lifetime: PhantomData<&'tree ()>,
}

impl<'tree, T: 'tree, Tree: Deref<Target = Octree<T>> + 'tree> View<'tree, Tree> {
    pub(crate) fn new(tree: Tree, target: u32) -> Self {
        Self {
            tree,
            target,
            _lifetime: PhantomData::default(),
        }
    }

    pub fn proxy(&self) -> &Proxy {
        &self.tree.proxies[self.target as usize]
    }

    pub fn parent(&self) -> Result<Self, Error>
    where
        Tree: Copy,
    {
        Ok(Self::new(self.tree, {
            let pid = self.proxy().parent;
            if pid == self.target {
                return Err(Error::ParentOfRoot);
            }
            pid
        }))
    }

    pub fn child(&self, index: u8) -> Result<Self, Error>
    where
        Tree: Copy,
    {
        Ok(Self::new(
            self.tree,
            match self.proxy().data {
                ProxyData::Branch(c) => {
                    *c.get(index as usize).ok_or(Error::ChildOutOfRange(index))?
                }
                _ => return Err(Error::NoChildren(self.target)),
            },
        ))
    }

    pub fn children(&self) -> Box<dyn Iterator<Item = Self> + '_>
    where
        Tree: Copy,
    {
        match self.proxy().data {
            ProxyData::Branch(c) => {
                Box::new(c.into_iter().map(|target| Self::new(self.tree, target)))
            }
            _ => Box::new([].into_iter()),
        }
    }
    pub fn data(&self) -> Option<&T> {
        match self.proxy().data {
            ProxyData::Leaf(lid) => Some(&self.tree.leaf_data[lid as usize]),
            _ => None,
        }
    }
}

impl<'tree, T: 'tree, Tree: DerefMut<Target = Octree<T>> + 'tree> View<'tree, Tree> {
    pub fn parent_mut(&mut self) -> Result<&mut Self, Error> {
        let pid = self.proxy().parent;
        if pid == self.target {
            return Err(Error::ParentOfRoot);
        }
        self.target = pid;
        Ok(self)
    }

    pub fn child_mut(&mut self, index: u8) -> Result<&mut Self, Error> {
        self.target = match self.proxy().data {
            ProxyData::Branch(c) => *c.get(index as usize).ok_or(Error::ChildOutOfRange(index))?,
            _ => return Err(Error::NoChildren(self.target)),
        };
        Ok(self)
    }
}