polyhedron 0.1.0

A half edge and radial edge implementation.
Documentation
use std::fmt;

/// ID for a topological vertex.
pub type VertId = TopoId<0, false>;
/// ID for a topological edgge.
pub type EdgeId = TopoId<1, false>;
/// ID for a topological half edge.
pub type HalfEdgeId = TopoId<1, true>;
/// ID for a topological face.
pub type FaceId = TopoId<2, false>;

/// Reserved value to indicate an empty topology element.
pub const VOID: usize = usize::MAX;

/// Topological id.
#[derive(Clone, Copy, PartialEq, PartialOrd, Ord, Eq, Hash)]
pub struct TopoId<const DIM: usize, const HALF: bool = false>(pub usize);

impl<const D: usize, const H: bool> Default for TopoId<D, H>
{
    fn default() -> Self { Self(VOID) }
}

impl<const D: usize, const H: bool> TopoId<D, H>
{
    /// Id from usize.
    pub fn new(id: usize) -> Self { Self(id) }

    /// See if the underlying topology type is invalid.
    pub fn is_void(&self) -> bool { self.0 == VOID }

    /// Convert the element to an index for indexing.
    pub fn to_index(&self) -> usize { self.0 }

    fn kind_str() -> &'static str
    {
        match (D, H)
        {
            (0, _) => "VertexId",
            (1, false) => "EdgeId",
            (1, true) => "HalfEdgeId",
            (2, _) => "FaceId",
            _ => "Unknown",
        }
    }
}

impl<const D: usize, const H: bool> std::fmt::Debug for TopoId<D, H>
{
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result
    {
        if self.is_void()
        {
            write!(f, "VOID")
        }
        else
        {
            write!(f, "{} {}", Self::kind_str(), self.0)
        }
    }
}

impl<const D: usize, const H: bool> fmt::Display for TopoId<D, H>
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
    {
        if self.is_void()
        {
            write!(f, "{}(VOID)", Self::kind_str())
        }
        else
        {
            write!(f, "{}({})", Self::kind_str(), self.0)
        }
    }
}