use std::fmt;
pub type VertId = TopoId<0, false>;
pub type EdgeId = TopoId<1, false>;
pub type HalfEdgeId = TopoId<1, true>;
pub type FaceId = TopoId<2, false>;
pub const VOID: usize = usize::MAX;
#[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>
{
pub fn new(id: usize) -> Self { Self(id) }
pub fn is_void(&self) -> bool { self.0 == VOID }
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)
}
}
}