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 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#[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}