use std::fmt::Debug;
use crate::Result;
use num_traits::ToBytes;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Uuid
{
data: u128,
}
impl Uuid
{
pub fn new() -> Self
{
Self {
data: uuid::Uuid::new_v4().as_u128(),
}
}
pub fn to_hex(&self) -> String
{
hex::encode(self.data.to_le_bytes())
}
pub fn to_string(&self) -> String
{
uuid::Uuid::from_u128(self.data).hyphenated().to_string()
}
pub fn from_string(input: &str) -> Result<Self>
{
Ok(
uuid::Uuid::parse_str(input)
.map_err(|e| crate::Error::InvalidUuid(input.to_string(), e.to_string()))?
.into(),
)
}
}
impl Default for Uuid
{
fn default() -> Self
{
Self::new()
}
}
impl From<uuid::Uuid> for Uuid
{
fn from(data: uuid::Uuid) -> Self
{
Self {
data: data.as_u128(),
}
}
}
impl From<u128> for Uuid
{
fn from(data: u128) -> Self
{
Self { data }
}
}
impl Into<u128> for Uuid
{
fn into(self) -> u128
{
self.data
}
}
impl Debug for Uuid
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
{
uuid::Uuid::from_u128(self.data).fmt(f)
}
}
impl serde::Serialize for Uuid
{
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(self.to_string().as_str())
}
}
struct UuidVisitor;
impl<'de> serde::de::Visitor<'de> for UuidVisitor
{
type Value = Uuid;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result
{
formatter.write_str("a valid UUID string")
}
fn visit_str<E>(self, v: &str) -> std::result::Result<Self::Value, E>
where
E: serde::de::Error,
{
Uuid::from_string(v).map_err(|e| {
E::custom(format!(
"Failed to parse UUID string {} with error {}",
v,
e.to_string()
))
})
}
fn visit_string<E>(self, v: String) -> std::result::Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_str(v.as_str())
}
}
impl<'de> serde::Deserialize<'de> for Uuid
{
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_str(UuidVisitor)
}
}