Skip to main content

ps_uuid/methods/
gen_dcom.rs

1use std::time::SystemTime;
2
3use crate::{UuidConstructionError, UUID};
4
5impl UUID {
6    /// Generates a new DCOM UUID using the current system time and the provided node ID.
7    ///
8    /// # Arguments
9    /// * `node_id` - The node ID (6 bytes)
10    ///
11    /// # Errors
12    /// - [`UuidConstructionError`] is returned if the system time is out of range.
13    pub fn gen_dcom(node_id: [u8; 6]) -> Result<Self, UuidConstructionError> {
14        Self::new_dcom(SystemTime::now(), node_id)
15    }
16}
17
18#[cfg(test)]
19mod tests {
20    #![allow(clippy::expect_used)]
21    use super::*;
22    use std::time::{Duration, SystemTime, UNIX_EPOCH};
23
24    #[test]
25    fn test_gen_dcom_success() {
26        let node_id = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB];
27        let uuid = UUID::gen_dcom(node_id);
28        assert!(
29            uuid.is_ok(),
30            "gen_dcom should succeed with current time and valid node_id"
31        );
32    }
33
34    #[test]
35    fn test_new_dcom_with_specific_node_id() {
36        let timestamp = SystemTime::now();
37        let node_id = [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF];
38        let uuid = UUID::new_dcom(timestamp, node_id);
39        assert!(uuid.is_ok(), "new_dcom should succeed with valid node_id");
40        // Optionally, check that the node_id is encoded in the UUID (if accessible)
41    }
42
43    #[test]
44    fn test_new_dcom_timestamp_before_epoch() {
45        let timestamp = UNIX_EPOCH - Duration::from_secs(1);
46        let node_id = [0u8; 6];
47        let result = UUID::new_dcom(timestamp, node_id);
48        assert!(
49            matches!(result, Err(UuidConstructionError::TimestampBeforeEpoch)),
50            "Should error with TimestampBeforeEpoch"
51        );
52    }
53
54    #[test]
55    fn test_new_dcom_timestamp_overflow() {
56        // Use a timestamp far in the future to trigger overflow
57        let timestamp = UNIX_EPOCH + Duration::from_secs(u64::MAX / 2);
58        let node_id = [0u8; 6];
59        let result = UUID::new_dcom(timestamp, node_id);
60        assert!(
61            matches!(result, Err(UuidConstructionError::TimestampOverflow)),
62            "Should error with TimestampOverflow"
63        );
64    }
65
66    #[test]
67    fn test_gen_dcom_determinism() {
68        // Same node_id and close timestamps should yield different UUIDs
69        let node_id = [1, 2, 3, 4, 5, 6];
70        let uuid1 =
71            UUID::gen_dcom(node_id).expect("DCOM UUID generation should succeed for valid input");
72        std::thread::sleep(std::time::Duration::from_millis(1));
73        let uuid2 =
74            UUID::gen_dcom(node_id).expect("DCOM UUID generation should succeed for valid input");
75        assert_ne!(
76            uuid1, uuid2,
77            "UUIDs generated at different times should differ"
78        );
79    }
80
81    #[test]
82    fn test_new_dcom_determinism() {
83        // Same timestamp and node_id should yield the same UUID
84        let timestamp = UNIX_EPOCH + Duration::from_secs(1_600_000_000);
85        let node_id = [1, 2, 3, 4, 5, 6];
86        let uuid1 = UUID::new_dcom(timestamp, node_id)
87            .expect("DCOM UUID generation should succeed for valid input");
88        let uuid2 = UUID::new_dcom(timestamp, node_id)
89            .expect("DCOM UUID generation should succeed for valid input");
90        assert_eq!(uuid1, uuid2, "Same input should yield same UUID");
91    }
92}