1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use crate::UUID;
// ────────────────────────────────────────────────────────────────────────────
// v6 constructor from individual wire-format fields
// ────────────────────────────────────────────────────────────────────────────
impl UUID {
/// Builds an RFC-4122 *Version 6* (time-ordered) UUID from its
/// constituent fields.
///
/// Timestamp layout (big-endian, network order):
/// - `time_high` – most-significant 32 bits of the 60-bit timestamp
/// - `time_mid` – next 16 bits of the timestamp
/// - `time_low` – least-significant 12 bits of the timestamp
///
/// Remaining fields:
/// - `clock_seq` – 14-bit clock sequence (high-to-low order)
/// - `node_id` – 48-bit node identifier (usually a MAC address)
///
/// The function performs all bit manipulation internally, then calls
/// `.with_version(6)` to patch in the *version* nibble (0b0110) and
/// the RFC-4122 variant bits (0b10xxxxxx). It never fails.
#[inline]
#[must_use]
pub fn from_parts_v6(
time_high: u32,
time_mid: u16,
time_low: u16,
clock_seq: u16,
node_id: [u8; 6],
) -> Self {
let mut uuid = Self::nil();
// Timestamp ---------------------------------------------------------
uuid.bytes[0..4].copy_from_slice(&time_high.to_be_bytes());
uuid.bytes[4..6].copy_from_slice(&time_mid.to_be_bytes());
uuid.bytes[6..8].copy_from_slice(&time_low.to_be_bytes());
// Clock sequence ----------------------------------------------------
uuid.bytes[8..10].copy_from_slice(&clock_seq.to_be_bytes());
// Node identifier ---------------------------------------------------
uuid.bytes[10..16].copy_from_slice(&node_id);
// Insert version + variant bits -------------------------------------
uuid.with_version(6)
}
}
#[cfg(test)]
mod tests {
use crate::{Variant, UUID};
#[test]
fn builds_correct_static_example() {
// Timestamp: 0x0123456789abcdef
// high 32 → 0x01234567
// mid 16 → 0x89ab
// low 12 → 0xcdef
// Clock-seq: 0x1234
// Node ID : 00-01-02-03-04-05
let uuid = UUID::from_parts_v6(
0x0123_4567,
0x89ab,
0xcdef,
0x1234,
[0x00, 0x01, 0x02, 0x03, 0x04, 0x05],
);
let b = uuid.as_bytes();
// time_high (bytes 0-3)
assert_eq!(&b[0..4], &[0x01, 0x23, 0x45, 0x67]);
// time_mid (bytes 4-5)
assert_eq!(&b[4..6], &[0x89, 0xab]);
// time_low & version (bytes 6-7)
// original 0xcd ef → version nibble patched ⇒ 0x6d ef
assert_eq!(b[6] & 0x0F, 0x0D);
assert_eq!(b[6] >> 4, 0x6);
assert_eq!(b[7], 0xEF);
// clock_seq & variant (bytes 8-9)
// original 0x12 34 → variant patch ⇒ 0x92 34
assert_eq!(b[9], 0x34);
assert_eq!(b[8] & 0x3F, 0x12);
assert_eq!(b[8] >> 6, 0b10);
// node_id (bytes 10-15)
assert_eq!(&b[10..16], &[0x00, 0x01, 0x02, 0x03, 0x04, 0x05]);
// High-level helpers
assert_eq!(uuid.get_version(), Some(6));
assert_eq!(uuid.get_variant(), Variant::OSF);
}
#[test]
fn nil_timestamp_yields_valid_uuid() {
let uuid = UUID::from_parts_v6(0, 0, 0, 0, [0; 6]);
assert_eq!(uuid.get_version(), Some(6));
assert_eq!(uuid.get_variant(), Variant::OSF);
// Only version & variant bits should be non-zero.
let mut expected = [0u8; 16];
expected[6] = 0x60; // version 6 nibble
expected[8] = 0x80; // variant 10xxxxxx
assert_eq!(uuid.as_bytes(), &expected);
}
#[test]
fn byte_order_is_big_endian() {
let uuid = UUID::from_parts_v6(1, 1, 1, 1, [0; 6]);
let b = uuid.as_bytes();
// Each field must appear in network order.
assert_eq!(&b[0..4], &[0x00, 0x00, 0x00, 0x01]); // time_high
assert_eq!(&b[4..6], &[0x00, 0x01]); // time_mid
assert_eq!(b[6], 0x60); // version nibble
assert_eq!(b[7], 0x01); // low byte of time_low
assert_eq!(b[9], 0x01); // low byte of clock_seq
}
}