simple_uuid/
rand.rs

1#![doc(cfg(feature = "rand_num"))]
2#![cfg(feature = "rand_num")]
3
4use crate::{Layout, Node, Variant, Version, UUID};
5use rand_core::{OsRng, RngCore};
6
7impl UUID {
8    /// New UUID version-4 from truly-random number
9    pub fn new_from_rand() -> Layout {
10        let mut key = [0u8; 128];
11        OsRng.fill_bytes(&mut key);
12
13        let random_u64_round_1 = OsRng.next_u64();
14        let round_1 = random_u64_round_1.to_le_bytes();
15
16        let random_u64_round_2 = OsRng.next_u64();
17        let round_2 = random_u64_round_2.to_le_bytes();
18
19        Layout {
20            field_low: ((round_1[0] as u32) << 24)
21                | (round_1[1] as u32) << 16
22                | (round_1[2] as u32) << 8
23                | round_1[3] as u32,
24            field_mid: (round_1[4] as u16) << 8 | (round_1[5] as u16),
25            field_high_and_version: ((round_1[6] as u16) << 8 | (round_1[7] as u16)) & 0xfff
26                | (Version::RAND as u16) << 12,
27            clock_seq_high_and_reserved: (round_2[0] & 0xf) | (Variant::RFC as u8) << 4,
28            clock_seq_low: round_2[1] as u8,
29            node: Node([
30                round_2[2], round_2[3], round_2[4], round_2[5], round_2[6], round_2[7],
31            ]),
32        }
33    }
34}
35
36/// `UUID` version-4
37#[doc(cfg(feature = "rand_num"))]
38#[macro_export]
39macro_rules! v4 {
40    () => {
41        format!("{:x}", $crate::UUID::new_from_rand().as_bytes())
42    };
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    #[test]
50    fn new_from_rand() {
51        let uuid = UUID::new_from_rand();
52        assert_eq!(uuid.get_version(), Some(Version::RAND));
53        assert_eq!(uuid.get_variant(), Some(Variant::RFC));
54    }
55}