1#![doc(cfg(feature = "mac_addr"))]
2#![cfg(feature = "mac_addr")]
3
4use mac_address;
5
6use crate::{Layout, Node, TimeStamp, Variant, Version, UUID};
7
8impl Layout {
9 pub const fn get_timestamp(&self) -> u64 {
11 self.field_low as u64
12 }
13
14 pub const fn get_mac_addr(&self) -> Node {
16 self.node
17 }
18
19 fn time_fields(utc: u64, clock_seq: (u8, u8), node: Node) -> Self {
20 Self {
21 field_low: (utc & 0xffff_ffff) as u32,
22 field_mid: ((utc >> 32 & 0xffff) as u16),
23 field_high_and_version: (utc >> 48 & 0xfff) as u16 | (Version::TIME as u16) << 12,
24 clock_seq_high_and_reserved: clock_seq.0,
25 clock_seq_low: clock_seq.1,
26 node: node,
27 }
28 }
29}
30
31impl UUID {
32 pub fn new_from_sys_time() -> Layout {
34 let clock_seq: (u8, u8) = crate::clock_seq_high_and_reserved(Variant::RFC as u8);
35 let utc = TimeStamp::new();
36 Layout::time_fields(utc, clock_seq, device_mac_addr())
37 }
38
39 pub fn new_from_node(node: Node) -> Layout {
41 let utc = TimeStamp::new();
42 let clock_seq = crate::clock_seq_high_and_reserved(Variant::RFC as u8);
43 Layout::time_fields(utc, clock_seq, node)
44 }
45
46 pub fn new_from_utc(utc: u64) -> Layout {
48 let clock_seq = crate::clock_seq_high_and_reserved(Variant::RFC as u8);
49 Layout::time_fields(utc, clock_seq, device_mac_addr())
50 }
51}
52
53fn device_mac_addr() -> Node {
54 Node(mac_address::get_mac_address().unwrap().unwrap().bytes())
55}
56
57#[doc(cfg(feature = "mac_addr"))]
59#[macro_export]
60macro_rules! v1 {
61 () => {
62 format!("{:x}", $crate::UUID::new_from_sys_time().as_bytes())
63 };
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn new_uuid_from_timestamp() {
72 let uuid = UUID::new_from_sys_time();
73 assert_eq!(uuid.get_version(), Some(Version::TIME));
74 assert_eq!(uuid.get_variant(), Some(Variant::RFC));
75 }
76
77 #[test]
78 fn new_uuid_from_user_defined_mac_address() {
79 let uuid = UUID::new_from_node(Node([0x03, 0x2a, 0x35, 0x0d, 0x13, 0x80]));
80 assert_eq!(uuid.get_version(), Some(Version::TIME));
81 assert_eq!(uuid.get_mac_addr().0, [0x03, 0x2a, 0x35, 0x0d, 0x13, 0x80]);
82 }
83
84 #[test]
85 fn new_uuid_from_custom_time() {
86 let uuid = UUID::new_from_utc(0x1234_u64);
87 assert_eq!(uuid.get_version(), Some(Version::TIME));
88 assert_eq!(uuid.get_timestamp(), 0x1234_u64);
89 }
90}