1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4use core::fmt;
7use uuid::Uuid;
8
9pub mod prelude;
10
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub enum UuidIdError {
13 InvalidFormat(String),
14}
15
16impl fmt::Display for UuidIdError {
17 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
18 match self {
19 Self::InvalidFormat(message) => formatter.write_str(message),
20 }
21 }
22}
23
24impl std::error::Error for UuidIdError {}
25
26#[must_use]
27pub fn is_uuid(input: &str) -> bool {
28 Uuid::parse_str(input).is_ok()
29}
30
31#[derive(Debug, Clone, PartialEq, Eq, Hash)]
32pub struct UuidId(Uuid);
33
34impl UuidId {
35 pub fn parse(input: &str) -> Result<Self, UuidIdError> {
41 Uuid::parse_str(input)
42 .map(Self)
43 .map_err(|error| UuidIdError::InvalidFormat(error.to_string()))
44 }
45
46 #[must_use]
47 pub const fn from_uuid(uuid: Uuid) -> Self {
48 Self(uuid)
49 }
50
51 #[must_use]
52 pub const fn as_uuid(&self) -> &Uuid {
53 &self.0
54 }
55
56 #[must_use]
57 pub fn to_hyphenated(&self) -> String {
58 self.0.hyphenated().to_string()
59 }
60
61 #[must_use]
62 pub fn to_simple(&self) -> String {
63 self.0.simple().to_string()
64 }
65}
66
67impl fmt::Display for UuidId {
68 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
69 formatter.write_str(&self.to_hyphenated())
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::{UuidId, is_uuid};
76
77 #[test]
78 fn uuid_validation_and_formatting_work() -> Result<(), Box<dyn std::error::Error>> {
79 let value = UuidId::parse("123e4567-e89b-12d3-a456-426614174000")?;
80 assert!(is_uuid(value.to_hyphenated().as_str()));
81 assert_eq!(value.to_simple(), "123e4567e89b12d3a456426614174000");
82 Ok(())
83 }
84}