axiolid_topology/
id.rs

1//! Typed arena handles prevent mixing vertex, edge, face, and shell indices.
2
3use core::fmt;
4
5macro_rules! topology_id {
6    ($name:ident, $label:literal) => {
7        #[doc = concat!("Stable handle into a B-rep ", $label, " arena.")]
8        #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
9        pub struct $name(u32);
10
11        impl $name {
12            pub(crate) fn from_index(index: usize) -> Self {
13                Self(u32::try_from(index).expect("topology arena exceeds u32 capacity"))
14            }
15
16            /// Zero-based arena index.
17            pub const fn index(self) -> usize {
18                self.0 as usize
19            }
20        }
21
22        impl fmt::Display for $name {
23            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24                write!(f, concat!($label, "#{}"), self.0)
25            }
26        }
27    };
28}
29
30topology_id!(VertexId, "vertex");
31topology_id!(EdgeId, "edge");
32topology_id!(LoopId, "loop");
33topology_id!(FaceId, "face");
34topology_id!(ShellId, "shell");
35topology_id!(SolidId, "solid");