altium_format/tree/
node.rs1use std::fmt;
4
5#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
11pub struct RecordId(u32);
12
13impl RecordId {
14 pub const ROOT: RecordId = RecordId(0);
16
17 #[inline]
19 pub const fn new(index: u32) -> Self {
20 RecordId(index)
21 }
22
23 #[inline]
25 pub const fn index(self) -> u32 {
26 self.0
27 }
28
29 #[inline]
31 pub fn from_usize(index: usize) -> Self {
32 RecordId(index as u32)
33 }
34
35 #[inline]
37 pub fn as_usize(self) -> usize {
38 self.0 as usize
39 }
40}
41
42impl fmt::Debug for RecordId {
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44 write!(f, "RecordId({})", self.0)
45 }
46}
47
48impl fmt::Display for RecordId {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 write!(f, "#{}", self.0)
51 }
52}
53
54impl From<u32> for RecordId {
55 fn from(index: u32) -> Self {
56 RecordId(index)
57 }
58}
59
60impl From<usize> for RecordId {
61 fn from(index: usize) -> Self {
62 RecordId(index as u32)
63 }
64}
65
66impl From<RecordId> for u32 {
67 fn from(id: RecordId) -> Self {
68 id.0
69 }
70}
71
72impl From<RecordId> for usize {
73 fn from(id: RecordId) -> Self {
74 id.0 as usize
75 }
76}
77
78#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
84pub enum ParentRef {
85 #[default]
87 Root,
88 Index(RecordId),
90}
91
92impl ParentRef {
93 pub fn from_owner_index(index: i32) -> Self {
98 if index < 0 {
99 ParentRef::Root
100 } else {
101 ParentRef::Index(RecordId::new(index as u32))
102 }
103 }
104
105 pub fn to_owner_index(self) -> i32 {
109 match self {
110 ParentRef::Root => -1,
111 ParentRef::Index(id) => id.0 as i32,
112 }
113 }
114
115 pub fn is_root(self) -> bool {
117 matches!(self, ParentRef::Root)
118 }
119
120 pub fn id(self) -> Option<RecordId> {
122 match self {
123 ParentRef::Root => None,
124 ParentRef::Index(id) => Some(id),
125 }
126 }
127}
128
129impl From<i32> for ParentRef {
130 fn from(index: i32) -> Self {
131 ParentRef::from_owner_index(index)
132 }
133}
134
135impl From<Option<RecordId>> for ParentRef {
136 fn from(id: Option<RecordId>) -> Self {
137 match id {
138 Some(id) => ParentRef::Index(id),
139 None => ParentRef::Root,
140 }
141 }
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147
148 #[test]
149 fn test_record_id() {
150 let id = RecordId::new(42);
151 assert_eq!(id.index(), 42);
152 assert_eq!(format!("{}", id), "#42");
153 assert_eq!(format!("{:?}", id), "RecordId(42)");
154 }
155
156 #[test]
157 fn test_parent_ref() {
158 assert!(ParentRef::Root.is_root());
159 assert!(!ParentRef::Index(RecordId::new(0)).is_root());
160
161 assert_eq!(ParentRef::from_owner_index(-1), ParentRef::Root);
162 assert_eq!(
163 ParentRef::from_owner_index(5),
164 ParentRef::Index(RecordId::new(5))
165 );
166
167 assert_eq!(ParentRef::Root.to_owner_index(), -1);
168 assert_eq!(ParentRef::Index(RecordId::new(5)).to_owner_index(), 5);
169 }
170}