hff_core/identifier/
mod.rs1use crate::{Ecc, Error, Result};
2use std::ops::{Deref, DerefMut};
3use uuid::Uuid;
4
5#[repr(u32)]
9#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
10pub enum IdType {
11 Id = 0,
13 Ecc2 = 1,
15 Uuid = 2,
17 Au8 = 3,
19 EccU64 = 4,
21 U64s = 5,
23}
24
25impl Deref for IdType {
26 type Target = u32;
27
28 fn deref(&self) -> &Self::Target {
29 match self {
30 Self::Id => &0,
31 Self::Ecc2 => &1,
32 Self::Uuid => &2,
33 Self::Au8 => &3,
34 Self::EccU64 => &4,
35 Self::U64s => &5,
36 }
37 }
38}
39
40impl From<u32> for IdType {
41 fn from(value: u32) -> Self {
42 match value {
43 0 => Self::Id,
44 1 => Self::Ecc2,
45 2 => Self::Uuid,
46 3 => Self::Au8,
47 4 => Self::EccU64,
48 5 => Self::U64s,
49 _ => panic!("Invalid identifier type in header."),
50 }
51 }
52}
53
54#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
56pub struct Identifier(u128);
57
58impl Identifier {
59 pub const INVALID: Self = Self(0);
61
62 pub fn new(id: u128) -> Self {
64 Self(id)
65 }
66
67 pub fn to_string(&self, id_type: IdType) -> String {
69 match id_type {
70 IdType::Id => format!("{:X}", self.0),
71 IdType::Ecc2 => {
72 let (p, s): (Ecc, Ecc) = (*self).into();
73 format!("{}:{}", p.to_string(), s.to_string())
74 }
75 IdType::Uuid => {
76 let id: Uuid = (*self).into();
77 format!("{}", id.to_string())
78 }
79 IdType::Au8 => {
80 let chars: [u8; 16] = (*self).into();
81 format!("{:?}", chars)
82 }
83 IdType::EccU64 => {
84 let (ecc, value): (Ecc, u64) = (*self).into();
85 format!("{}:{:X}", ecc.to_string(), value)
86 }
87 IdType::U64s => {
88 let (l, r): (u64, u64) = (*self).into();
89 format!("{:X}:{:X}", l, r)
90 }
91 }
92 }
93
94 pub fn as_u64s(self) -> (u64, u64) {
98 ((self.0 >> 64) as u64, self.0 as u64)
99 }
100
101 pub fn as_ecc2(self) -> (Ecc, Ecc) {
103 let (l, r) = self.as_u64s();
104 (l.into(), r.into())
105 }
106
107 pub fn as_uuid(self) -> Uuid {
109 Uuid::from_u128(self.0)
110 }
111
112 pub fn as_au8(self) -> [u8; 16] {
114 #[cfg(target_endian = "little")]
115 {
116 self.0.to_le_bytes()
117 }
118
119 #[cfg(target_endian = "big")]
120 {
121 self.0.to_be_bytes()
122 }
123 }
124
125 pub fn as_eccu64(self) -> (Ecc, u64) {
127 let (ecc, value) = self.as_u64s();
128 (Ecc::from(ecc), value)
129 }
130}
131
132impl Deref for Identifier {
133 type Target = u128;
134
135 fn deref(&self) -> &Self::Target {
136 &self.0
137 }
138}
139
140impl DerefMut for Identifier {
141 fn deref_mut(&mut self) -> &mut Self::Target {
142 &mut self.0
143 }
144}
145
146impl Into<u128> for Identifier {
147 fn into(self) -> u128 {
148 self.0
149 }
150}
151
152impl Into<(Ecc, Ecc)> for Identifier {
153 fn into(self) -> (Ecc, Ecc) {
154 self.as_ecc2()
155 }
156}
157
158impl Into<Uuid> for Identifier {
159 fn into(self) -> Uuid {
160 self.as_uuid()
161 }
162}
163
164impl Into<[u8; 16]> for Identifier {
165 fn into(self) -> [u8; 16] {
166 self.as_au8()
167 }
168}
169
170impl Into<(Ecc, u64)> for Identifier {
171 fn into(self) -> (Ecc, u64) {
172 self.as_eccu64()
173 }
174}
175
176impl Into<(u64, u64)> for Identifier {
177 fn into(self) -> (u64, u64) {
178 self.as_u64s()
179 }
180}
181
182impl From<u128> for Identifier {
186 fn from(value: u128) -> Self {
187 Self(value)
188 }
189}
190
191impl From<(Ecc, Ecc)> for Identifier {
193 fn from(value: (Ecc, Ecc)) -> Self {
194 let primary: u64 = *value.0;
195 let secondary: u64 = *value.1;
196 let value = (primary as u128) << 64 | (secondary as u128);
197 Self(value)
198 }
199}
200
201impl From<Uuid> for Identifier {
203 fn from(value: Uuid) -> Self {
204 Self(value.as_u128())
205 }
206}
207
208impl From<[u8; 16]> for Identifier {
210 fn from(value: [u8; 16]) -> Self {
211 #[cfg(target_endian = "little")]
212 let value = u128::from_le_bytes(value);
213 #[cfg(target_endian = "big")]
214 let value = u128::from_be_bytes(value);
215
216 Self(value)
217 }
218}
219
220impl From<(Ecc, u64)> for Identifier {
222 fn from(value: (Ecc, u64)) -> Self {
223 let ecc: u64 = *value.0;
224 let value = (ecc as u128) << 64 | (value.1 as u128);
225 Self(value)
226 }
227}
228
229impl From<(u64, u64)> for Identifier {
231 fn from(value: (u64, u64)) -> Self {
232 let value = (value.0 as u128) << 64 | (value.1 as u128);
233 Self(value)
234 }
235}
236
237impl TryFrom<(&str, &str)> for Identifier {
238 type Error = Error;
239
240 fn try_from(value: (&str, &str)) -> Result<Self> {
241 let primary: Ecc = value.0.try_into()?;
242 let secondary: Ecc = value.1.try_into()?;
243 Ok((primary, secondary).try_into()?)
244 }
245}
246
247impl TryFrom<(&str, u64)> for Identifier {
248 type Error = Error;
249
250 fn try_from(value: (&str, u64)) -> Result<Self> {
251 let ecc: Ecc = value.0.try_into()?;
252 Ok((ecc, value.1).try_into()?)
253 }
254}
255
256#[cfg(test)]
257mod tests {
258 use super::*;
259
260 #[test]
261 fn test_ecc2() {
262 let identifier: Identifier = (123, 456).try_into().unwrap();
263 let (_123, _456) = identifier.as_u64s();
264 assert_eq!(_123, 123);
265 assert_eq!(_456, 456);
266 }
267}