ps_uuid/methods/
from_parts_v5.rs1use crate::UUID;
2
3impl UUID {
8 #[must_use]
15 pub fn from_parts_v5<D>(digest: D) -> Self
16 where
17 D: AsRef<[u8]>,
18 {
19 let digest = digest.as_ref();
20 let mut uuid = Self::nil();
21
22 uuid.bytes[..digest.len().min(16)].copy_from_slice(&digest[..digest.len().min(16)]);
23
24 uuid.with_version(5)
25 }
26}
27
28#[cfg(test)]
32mod tests {
33 #![allow(clippy::cast_possible_truncation, clippy::expect_used)]
34 use std::str::FromStr;
35
36 use crate::{sha1, UUID};
37
38 const fn is_rfc4122_variant(b: u8) -> bool {
40 (b & 0b1100_0000) == 0b1000_0000
41 }
42
43 #[test]
44 fn sets_version_and_variant_correctly() {
45 for &input in &[[0u8; 20], [0xFFu8; 20]] {
46 let uuid = UUID::from_parts_v5(input);
47 assert_eq!(uuid.get_version(), Some(5));
48 assert!(is_rfc4122_variant(uuid.bytes[8]));
49 }
50 }
51
52 #[test]
53 fn preserves_all_other_bits() {
54 let mut digest = [0u8; 20];
55 for (i, b) in digest.iter_mut().enumerate() {
56 *b = i as u8;
57 }
58
59 let uuid = UUID::from_parts_v5(digest);
60
61 for i in 0..16 {
62 match i {
63 6 => assert_eq!(uuid.bytes[6] & 0x0F, digest[6] & 0x0F),
65 8 => assert_eq!(uuid.bytes[8] & 0x3F, digest[8] & 0x3F),
67 _ => assert_eq!(uuid.bytes[i], digest[i]),
68 }
69 }
70 }
71
72 #[test]
73 fn matches_rfc_reference_example() {
74 let ns = UUID::from_str("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
76 .expect("failed to parse UUID test vector");
77 let name = b"python.org";
78
79 let digest = sha1(&[&ns.bytes[..], name].concat());
81 let via_parts = UUID::from_parts_v5(digest);
82
83 let expected = UUID::from_str("886313e1-3b8a-5372-9b90-0c9aee199e5d")
85 .expect("failed to parse UUID test vector");
86
87 assert_eq!(via_parts.bytes, expected.bytes);
88 }
89}