use core::fmt;
use reliar_core::IdError;
use uuid::Uuid;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct WorkerId(String);
impl WorkerId {
pub const MAX_LEN: usize = 128;
#[must_use]
pub fn generate() -> Self {
let pid = std::process::id();
let id = Uuid::now_v7();
Self(format!("{pid}:{id}"))
}
pub fn parse(s: impl Into<String>) -> Result<Self, IdError> {
let s = s.into();
if s.is_empty() {
return Err(IdError::Empty);
}
if s.len() > Self::MAX_LEN {
return Err(IdError::TooLong {
len: s.len(),
max: Self::MAX_LEN,
});
}
Ok(Self(s))
}
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
}
}
impl Default for WorkerId {
fn default() -> Self {
Self::generate()
}
}
impl fmt::Display for WorkerId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.0)
}
}
#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
mod serde_impl {
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error as _};
use super::WorkerId;
impl Serialize for WorkerId {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
s.collect_str(&self.0)
}
}
impl<'de> Deserialize<'de> for WorkerId {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
let raw = String::deserialize(d)?;
WorkerId::parse(raw).map_err(D::Error::custom)
}
}
}