1use std::fmt;
2
3#[repr(C)]
5#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
6pub struct Guid {
7 pub data1: u32,
8 pub data2: u16,
9 pub data3: u16,
10 pub data4: [u8; 8],
11}
12
13impl Guid {
14 pub const ZERO: Guid = Guid::new(0, 0, 0, [0; 8]);
15
16 pub const fn new(data1: u32, data2: u16, data3: u16, data4: [u8; 8]) -> Self {
17 Guid { data1, data2, data3, data4 }
18 }
19
20 pub const fn from_u128(v: u128) -> Self {
23 let b = v.to_be_bytes();
24 Guid {
25 data1: u32::from_be_bytes([b[0], b[1], b[2], b[3]]),
26 data2: u16::from_be_bytes([b[4], b[5]]),
27 data3: u16::from_be_bytes([b[6], b[7]]),
28 data4: [b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]],
29 }
30 }
31
32 pub fn parse(s: &str) -> Option<Guid> {
34 let s = s.trim().trim_start_matches('{').trim_end_matches('}');
35 let hex: String = s.chars().filter(|c| *c != '-').collect();
36 if hex.len() != 32 || s.len() != 36 {
37 return None;
38 }
39 u128::from_str_radix(&hex, 16).ok().map(Guid::from_u128)
40 }
41
42 pub const fn as_com_h_materialized(&self) -> Guid {
50 let d = self.data4;
51 Guid {
52 data1: self.data1,
53 data2: self.data2,
54 data3: self.data3,
55 data4: [d[0], d[1], d[1], d[1], d[1], d[1], d[1], d[1]],
56 }
57 }
58}
59
60impl fmt::Display for Guid {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62 let d = &self.data4;
63 write!(
64 f,
65 "{:08x}-{:04x}-{:04x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
66 self.data1, self.data2, self.data3, d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7]
67 )
68 }
69}
70
71impl fmt::Debug for Guid {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 write!(f, "Guid({self})")
74 }
75}