graph_core/id.rs
1/// A type-safe node identifier.
2///
3/// Wraps a `usize` index so a [`NodeId`] can never be accidentally passed
4/// where an [`EdgeId`] (or a raw `usize`) is expected. The wrapper is
5/// zero-cost — the compiler erases it entirely.
6///
7/// # Examples
8///
9/// ```
10/// use graph_core::NodeId;
11///
12/// let a = NodeId::new(0);
13/// let b = NodeId::new(1);
14/// assert_ne!(a, b);
15/// assert_eq!(a.index(), 0);
16/// ```
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
18pub struct NodeId(usize);
19
20/// A type-safe edge identifier.
21///
22/// Wraps a `usize` index so an [`EdgeId`] can never be accidentally passed
23/// where a [`NodeId`] is expected.
24///
25/// # Examples
26///
27/// ```
28/// use graph_core::EdgeId;
29///
30/// let e = EdgeId::new(3);
31/// assert_eq!(e.index(), 3);
32/// ```
33#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
34pub struct EdgeId(usize);
35
36// ── NodeId ────────────────────────────────────────────────────────────────────
37
38impl NodeId {
39 /// Creates a new [`NodeId`] from a raw index.
40 ///
41 /// # Examples
42 ///
43 /// ```
44 /// use graph_core::NodeId;
45 ///
46 /// let id = NodeId::new(42);
47 /// assert_eq!(id.index(), 42);
48 /// ```
49 #[inline]
50 pub fn new(idx: usize) -> Self {
51 NodeId(idx)
52 }
53
54 /// Returns the underlying `usize` index.
55 ///
56 /// # Examples
57 ///
58 /// ```
59 /// use graph_core::NodeId;
60 ///
61 /// assert_eq!(NodeId::new(7).index(), 7);
62 /// ```
63 #[must_use]
64 #[inline]
65 pub fn index(self) -> usize {
66 self.0
67 }
68}
69
70impl From<usize> for NodeId {
71 /// Converts a `usize` into a [`NodeId`].
72 ///
73 /// # Examples
74 ///
75 /// ```
76 /// use graph_core::NodeId;
77 ///
78 /// let id: NodeId = 5usize.into();
79 /// assert_eq!(id.index(), 5);
80 /// ```
81 #[inline]
82 fn from(i: usize) -> Self {
83 NodeId(i)
84 }
85}
86
87impl std::fmt::Display for NodeId {
88 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89 write!(f, "NodeId({})", self.0)
90 }
91}
92
93// ── EdgeId ────────────────────────────────────────────────────────────────────
94
95impl EdgeId {
96 /// Creates a new [`EdgeId`] from a raw index.
97 ///
98 /// # Examples
99 ///
100 /// ```
101 /// use graph_core::EdgeId;
102 ///
103 /// let id = EdgeId::new(0);
104 /// assert_eq!(id.index(), 0);
105 /// ```
106 #[inline]
107 pub fn new(idx: usize) -> Self {
108 EdgeId(idx)
109 }
110
111 /// Returns the underlying `usize` index.
112 ///
113 /// # Examples
114 ///
115 /// ```
116 /// use graph_core::EdgeId;
117 ///
118 /// assert_eq!(EdgeId::new(2).index(), 2);
119 /// ```
120 #[must_use]
121 #[inline]
122 pub fn index(self) -> usize {
123 self.0
124 }
125}
126
127impl From<usize> for EdgeId {
128 /// Converts a `usize` into an [`EdgeId`].
129 ///
130 /// # Examples
131 ///
132 /// ```
133 /// use graph_core::EdgeId;
134 ///
135 /// let id: EdgeId = 9usize.into();
136 /// assert_eq!(id.index(), 9);
137 /// ```
138 #[inline]
139 fn from(i: usize) -> Self {
140 EdgeId(i)
141 }
142}
143
144impl std::fmt::Display for EdgeId {
145 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
146 write!(f, "EdgeId({})", self.0)
147 }
148}