conspire 0.7.1

The Rust interface to conspire.
Documentation
use crate::geometry::ntree::{
    Orthotree,
    node::{Kind, Node},
    subdivide::insert_bit,
};
use std::array::from_fn;

impl<const D: usize, const L: usize, const M: usize, const N: usize, T, U>
    Orthotree<D, L, M, N, T, U>
where
    T: Copy + Into<usize>,
    U: Copy + Into<usize>,
{
    pub fn all_leaves<'a>(&self, node: &'a Node<D, M, N, T, U>) -> Option<&'a [U; N]> {
        match &node.kind {
            Kind::Leaf => None,
            Kind::Tree(orthants) => {
                if orthants.iter().any(|&orthant| self[orthant].is_tree()) {
                    None
                } else {
                    Some(orthants)
                }
            }
        }
    }
    pub fn leaves(&self, node: &Node<D, M, N, T, U>) -> [Option<U>; N] {
        match &node.kind {
            Kind::Leaf => [None; N],
            Kind::Tree(orthants) => from_fn(|i| {
                if self[orthants[i]].is_leaf() {
                    Some(orthants[i])
                } else {
                    None
                }
            }),
        }
    }
    pub fn leaves_on_facet(&self, node: &Node<D, M, N, T, U>, facet: usize) -> [Option<U>; L] {
        let (axis, side) = (facet >> 1, facet & 1);
        match &node.kind {
            Kind::Leaf => from_fn(|_| None),
            Kind::Tree(orthants) => from_fn(|i| {
                let orthant = orthants[insert_bit(i, axis, side)];
                self[orthant].is_leaf().then_some(orthant)
            }),
        }
    }
    pub fn leaves_and_facets(
        &self,
        node: &Node<D, M, N, T, U>,
    ) -> [Option<(U, [Option<U>; D])>; N] {
        match &node.kind {
            Kind::Leaf => from_fn(|_| None),
            Kind::Tree(orthants) => from_fn(|i| {
                let orthant = orthants[i];
                if self[orthant].is_leaf() {
                    let facets = &self[orthant].facets;
                    let external: [Option<U>; D] = from_fn(|b| facets[2 * b + ((i >> b) & 1)]);
                    Some((orthant, external))
                } else {
                    None
                }
            }),
        }
    }
    pub fn orthants_leaves(&self, node: &Node<D, M, N, T, U>) -> [Option<[Option<U>; N]>; N] {
        match &node.kind {
            Kind::Leaf => from_fn(|_| None),
            Kind::Tree(orthants) => from_fn(|i| match &self[orthants[i]].kind {
                Kind::Leaf => None,
                Kind::Tree(sub_orthants) => {
                    let inner: [Option<U>; N] = from_fn(|j| {
                        if self[sub_orthants[j]].is_leaf() {
                            Some(sub_orthants[j])
                        } else {
                            None
                        }
                    });
                    if inner.iter().any(|x| x.is_some()) {
                        Some(inner)
                    } else {
                        None
                    }
                }
            }),
        }
    }
    pub fn orthants_leaves_on_facet(
        &self,
        node: &Node<D, M, N, T, U>,
        face: usize,
    ) -> [Option<[Option<U>; L]>; L] {
        let (axis, side) = (face >> 1, face & 1);
        match &node.kind {
            Kind::Leaf => from_fn(|_| None),
            Kind::Tree(orthants) => {
                from_fn(|i| match &self[orthants[insert_bit(i, axis, side)]].kind {
                    Kind::Leaf => None,
                    Kind::Tree(sub_orthants) => {
                        let inner: [Option<U>; L] = from_fn(|j| {
                            let leaf = sub_orthants[insert_bit(j, axis, side)];
                            self[leaf].is_leaf().then_some(leaf)
                        });
                        inner.iter().any(|x| x.is_some()).then_some(inner)
                    }
                })
            }
        }
    }
    pub fn orthants_all_leaves_on_facet(
        &self,
        node: &Node<D, M, N, T, U>,
        face: usize,
    ) -> Option<[[U; L]; L]> {
        let orthants_leaves = self.orthants_leaves_on_facet(node, face);
        orthants_leaves
            .iter()
            .all(|&orthant| orthant.is_some_and(|leaves| leaves.iter().all(Option::is_some)))
            .then(|| from_fn(|i| from_fn(|j| orthants_leaves[i].unwrap()[j].unwrap())))
    }
}