Skip to main content

ps_uuid/methods/
from_parts_v8.rs

1use crate::UUID;
2
3impl UUID {
4    /// Constructs a Version 8 (custom) UUID from 16 bytes.
5    ///
6    /// The version and variant fields are set according to RFC 4122.
7    #[must_use]
8    pub const fn from_parts_v8(bytes: [u8; 16]) -> Self {
9        Self::from_bytes(bytes).with_version(8)
10    }
11}
12
13#[allow(clippy::cast_possible_truncation)]
14#[cfg(test)]
15mod tests {
16    use crate::{Variant, UUID};
17
18    #[test]
19    fn sets_version_and_variant_correctly() {
20        // All zeros
21        let uuid = UUID::from_parts_v8([0u8; 16]);
22        assert_eq!(uuid.bytes[6] >> 4, 0b1000, "Version must be 8");
23        assert_eq!(
24            uuid.bytes[8] & 0b1100_0000,
25            0b1000_0000,
26            "Variant must be RFC 4122"
27        );
28
29        // All ones
30        let uuid = UUID::from_parts_v8([0xFFu8; 16]);
31        assert_eq!(uuid.bytes[6] >> 4, 0b01000, "Version must be 8");
32        assert_eq!(
33            uuid.bytes[8] & 0b1100_0000,
34            0b1000_0000,
35            "Variant must be RFC 4122"
36        );
37
38        // Random pattern
39        let mut input = [0xABu8; 16];
40        input[6] = 0x12;
41        input[8] = 0x34;
42        let uuid = UUID::from_parts_v8(input);
43        assert_eq!(uuid.bytes[6] >> 4, 0b1000, "Version must be 8");
44        assert_eq!(
45            uuid.bytes[8] & 0b1100_0000,
46            0b1000_0000,
47            "Variant must be RFC 4122"
48        );
49    }
50
51    #[test]
52    fn preserves_other_bytes() {
53        let mut input = [0u8; 16];
54
55        for (i, item) in input.iter_mut().enumerate() {
56            *item = i as u8;
57        }
58
59        let uuid = UUID::from_parts_v8(input);
60
61        // Only bytes 6 and 8 are changed
62        for i in 0..16 {
63            if i == 6 {
64                assert_eq!(uuid.bytes[6] & 0xF0, 0x80, "Version bits must be set");
65            } else if i == 8 {
66                assert_eq!(uuid.bytes[8] & 0xC0, 0x80, "Variant bits must be set");
67            } else {
68                assert_eq!(uuid.bytes[i], i as u8, "Other bytes must be unchanged");
69            }
70        }
71    }
72
73    #[test]
74    fn version_and_variant_are_reported() {
75        let uuid = UUID::from_parts_v8([0u8; 16]);
76        assert_eq!(uuid.get_version(), Some(8));
77        assert_eq!(uuid.get_variant(), Variant::OSF);
78    }
79
80    #[test]
81    fn preserves_all_payload_bits() {
82        let mut src = [0u8; 16];
83        for (i, b) in src.iter_mut().enumerate() {
84            *b = i as u8;
85        }
86
87        let uuid = UUID::from_parts_v8(src);
88
89        for i in 0..16 {
90            match i {
91                6 => {
92                    // High nibble overwritten, low nibble kept
93                    assert_eq!(uuid.bytes[6] & 0x0F, src[6] & 0x0F);
94                    assert_eq!(uuid.bytes[6] >> 4, 0x8);
95                }
96                8 => {
97                    // Top two bits overwritten, lower six preserved
98                    assert_eq!(uuid.bytes[8] & 0x3F, src[8] & 0x3F);
99                    assert_eq!(uuid.bytes[8] >> 6, 0b10);
100                }
101                _ => assert_eq!(uuid.bytes[i], src[i], "byte {i} must be unchanged"),
102            }
103        }
104    }
105
106    // -----------------------------------------------------------
107    // Public getters
108    // -----------------------------------------------------------
109    #[test]
110    fn version_and_variant_helpers_report_correctly() {
111        let uuid = UUID::from_parts_v8([0u8; 16]);
112        assert_eq!(uuid.get_version(), Some(8));
113        assert_eq!(uuid.get_variant(), Variant::OSF);
114    }
115
116    // -----------------------------------------------------------
117    // Compile-time construction
118    // -----------------------------------------------------------
119    const CONST_V8: UUID = UUID::from_parts_v8([1; 16]);
120
121    #[test]
122    fn const_construction_matches_runtime() {
123        let rt = UUID::from_parts_v8([1; 16]);
124        assert_eq!(CONST_V8.bytes, rt.bytes);
125    }
126}