Skip to main content

ps_uuid/methods/
fmt_hyphenated.rs

1//! Hyphenated formatting for UUID.
2
3use core::fmt;
4
5use crate::UUID;
6
7/// A UUID formatted in the canonical hyphenated representation.
8///
9/// Created by calling [`UUID::hyphenated()`], this wrapper implements [`Display`]
10/// to render the UUID in the standard 8-4-4-4-12 format defined by RFC 4122.
11///
12/// ```text
13/// 550e8400-e29b-41d4-a716-446655440000
14/// ```
15///
16/// [`Display`]: core::fmt::Display
17#[derive(Clone, Copy, Debug)]
18pub struct Hyphenated(UUID);
19
20impl fmt::Display for Hyphenated {
21    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22        let b = &self.0.bytes;
23        write!(
24            f,
25            "{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
26            b[0], b[1], b[2], b[3],
27            b[4], b[5],
28            b[6], b[7],
29            b[8], b[9],
30            b[10], b[11], b[12], b[13], b[14], b[15]
31        )
32    }
33}
34
35impl From<Hyphenated> for UUID {
36    #[inline]
37    fn from(hyphenated: Hyphenated) -> Self {
38        hyphenated.0
39    }
40}
41
42impl UUID {
43    /// Returns a formatter for the hyphenated (standard) format.
44    ///
45    /// This produces the same output as the `Display` implementation.
46    ///
47    /// # Example
48    ///
49    /// ```
50    /// use ps_uuid::UUID;
51    ///
52    /// let uuid = UUID::nil();
53    /// assert_eq!(uuid.hyphenated().to_string(), "00000000-0000-0000-0000-000000000000");
54    /// ```
55    #[inline]
56    #[must_use]
57    pub const fn hyphenated(self) -> Hyphenated {
58        Hyphenated(self)
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    #![allow(clippy::expect_used)]
65    use crate::UUID;
66
67    #[test]
68    fn nil_formats_correctly() {
69        assert_eq!(
70            UUID::nil().hyphenated().to_string(),
71            "00000000-0000-0000-0000-000000000000"
72        );
73    }
74
75    #[test]
76    fn max_formats_correctly() {
77        assert_eq!(
78            UUID::max().hyphenated().to_string(),
79            "ffffffff-ffff-ffff-ffff-ffffffffffff"
80        );
81    }
82
83    #[test]
84    fn hyphenated_has_correct_length() {
85        let uuid = UUID::gen_v4();
86        let hyphenated = uuid.hyphenated().to_string();
87        assert_eq!(hyphenated.len(), 36);
88    }
89
90    #[test]
91    fn hyphenated_has_hyphens_at_correct_positions() {
92        let uuid = UUID::gen_v4();
93        let hyphenated = uuid.hyphenated().to_string();
94        let chars: Vec<char> = hyphenated.chars().collect();
95        assert_eq!(chars[8], '-');
96        assert_eq!(chars[13], '-');
97        assert_eq!(chars[18], '-');
98        assert_eq!(chars[23], '-');
99    }
100
101    #[test]
102    fn hyphenated_matches_display() {
103        let uuid = UUID::gen_v4();
104        assert_eq!(uuid.hyphenated().to_string(), uuid.to_string());
105    }
106
107    #[test]
108    fn hyphenated_is_lowercase_hex() {
109        let uuid = UUID::from_bytes([
110            0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56,
111            0x78, 0x9A,
112        ]);
113        let hyphenated = uuid.hyphenated().to_string();
114        assert_eq!(hyphenated, "abcdef12-3456-789a-bcde-f0123456789a");
115    }
116
117    #[test]
118    fn round_trip_parse() {
119        let uuid = UUID::gen_v4();
120        let hyphenated = uuid.hyphenated().to_string();
121        let parsed: UUID = hyphenated.parse().expect("hyphenated format should parse");
122        assert_eq!(parsed, uuid);
123    }
124}