1use std::{fmt, num::NonZeroU128};
5
6use crate::{
7 error::{Error, ErrorKind},
8 Uuid,
9};
10
11#[repr(transparent)]
35#[derive(#[automatically_derived]
impl ::core::marker::Copy for NonNilUuid { }Copy, #[automatically_derived]
impl ::core::clone::Clone for NonNilUuid {
#[inline]
fn clone(&self) -> NonNilUuid {
let _: ::core::clone::AssertParamIsClone<NonZeroU128>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for NonNilUuid {
#[inline]
fn eq(&self, other: &NonNilUuid) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for NonNilUuid {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {
let _: ::core::cmp::AssertParamIsEq<NonZeroU128>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for NonNilUuid {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
::core::hash::Hash::hash(&self.0, state)
}
}Hash)]
36pub struct NonNilUuid(NonZeroU128);
37
38impl fmt::Debug for NonNilUuid {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 fmt::Debug::fmt(&Uuid::from(*self), f)
41 }
42}
43
44impl fmt::Display for NonNilUuid {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 fmt::Display::fmt(&Uuid::from(*self), f)
47 }
48}
49
50impl PartialEq<Uuid> for NonNilUuid {
51 fn eq(&self, other: &Uuid) -> bool {
52 self.get() == *other
53 }
54}
55
56impl PartialEq<NonNilUuid> for Uuid {
57 fn eq(&self, other: &NonNilUuid) -> bool {
58 *self == other.get()
59 }
60}
61
62impl NonNilUuid {
63 pub const fn new(uuid: Uuid) -> Option<Self> {
65 match NonZeroU128::new(uuid.as_u128()) {
66 Some(non_nil) => Some(NonNilUuid(non_nil)),
67 None => None,
68 }
69 }
70
71 pub const unsafe fn new_unchecked(uuid: Uuid) -> Self {
77 NonNilUuid(unsafe { NonZeroU128::new_unchecked(uuid.as_u128()) })
78 }
79
80 #[inline]
82 pub const fn get(self) -> Uuid {
83 Uuid::from_u128(self.0.get())
84 }
85}
86
87impl From<NonNilUuid> for Uuid {
88 fn from(non_nil: NonNilUuid) -> Self {
100 Uuid::from_u128(non_nil.0.get())
101 }
102}
103
104impl TryFrom<Uuid> for NonNilUuid {
105 type Error = Error;
106
107 fn try_from(uuid: Uuid) -> Result<Self, Self::Error> {
116 NonZeroU128::new(uuid.as_u128())
117 .map(Self)
118 .ok_or(Error(ErrorKind::Nil))
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125
126 #[test]
127 fn test_non_nil_with_option_size() {
128 assert_eq!(
129 std::mem::size_of::<Option<NonNilUuid>>(),
130 std::mem::size_of::<Uuid>()
131 );
132 }
133
134 #[test]
135 fn test_non_nil() {
136 let uuid = Uuid::from_u128(0x0123456789abcdef0123456789abcdef);
137
138 assert_eq!(Uuid::from(NonNilUuid::try_from(uuid).unwrap()), uuid);
139 assert_eq!(NonNilUuid::new(uuid).unwrap(), uuid);
140 assert_eq!(unsafe { NonNilUuid::new_unchecked(uuid) }, uuid);
141
142 assert!(NonNilUuid::try_from(Uuid::nil()).is_err());
143 assert!(NonNilUuid::new(Uuid::nil()).is_none());
144 }
145
146 #[test]
147 fn test_non_nil_formatting() {
148 let uuid = Uuid::from_u128(0x0123456789abcdef0123456789abcdef);
149 let non_nil = NonNilUuid::try_from(uuid).unwrap();
150
151 assert_eq!(format!("{uuid}"), format!("{non_nil}"));
152 assert_eq!(format!("{uuid:?}"), format!("{non_nil:?}"));
153 }
154}