simple_uuid/
time.rs

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    /// Get timestamp where the UUID generated in
10    pub const fn get_timestamp(&self) -> u64 {
11        self.field_low as u64
12    }
13
14    /// Get the MAC-address where the UUID generated with
15    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    /// New UUID version-1
33    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    /// New UUID with a user defined MAC-address
40    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    /// New UUID with specific timestamp
47    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/// `UUID` version-1
58#[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}