use std::str::FromStr;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct SessionId(pub Uuid);
impl SessionId {
pub fn new() -> Self {
Self(Uuid::new_v4())
}
pub fn parse(s: &str) -> Option<Self> {
Uuid::parse_str(s).ok().map(Self)
}
}
impl Default for SessionId {
fn default() -> Self {
Self::new()
}
}
impl std::fmt::Display for SessionId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl FromStr for SessionId {
type Err = uuid::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Uuid::parse_str(s).map(Self)
}
}
impl From<Uuid> for SessionId {
fn from(uuid: Uuid) -> Self {
Self(uuid)
}
}
impl From<&str> for SessionId {
fn from(s: &str) -> Self {
Self::parse(s).unwrap_or_default()
}
}
impl From<String> for SessionId {
fn from(s: String) -> Self {
Self::from(s.as_str())
}
}
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct MessageId(pub String);
impl MessageId {
pub fn new() -> Self {
Self(Uuid::new_v4().to_string())
}
pub fn from_string(s: impl Into<String>) -> Self {
Self(s.into())
}
}
impl Default for MessageId {
fn default() -> Self {
Self::new()
}
}
impl std::fmt::Display for MessageId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl FromStr for MessageId {
type Err = std::convert::Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(s.to_string()))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_session_id_generation() {
let id1 = SessionId::new();
let id2 = SessionId::new();
assert_ne!(id1, id2);
}
#[test]
fn test_session_id_parse() {
let id = SessionId::new();
let parsed = SessionId::parse(&id.to_string());
assert_eq!(parsed, Some(id));
}
#[test]
fn test_message_id_generation() {
let id1 = MessageId::new();
let id2 = MessageId::new();
assert_ne!(id1, id2);
}
}