use std::fmt;
use uuid::Uuid;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ConnectionId(Uuid);
impl ConnectionId {
#[must_use]
pub fn new() -> Self {
Self(Uuid::new_v4())
}
#[must_use]
pub fn as_uuid(&self) -> Uuid {
self.0
}
}
impl Default for ConnectionId {
fn default() -> Self {
Self::new()
}
}
impl fmt::Display for ConnectionId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl From<Uuid> for ConnectionId {
fn from(uuid: Uuid) -> Self {
Self(uuid)
}
}
#[derive(Debug, Clone)]
pub struct SseConnection {
pub id: ConnectionId,
pub user_id: Option<String>,
pub client_ip: Option<String>,
pub last_event_id: Option<String>,
pub subscribed_channels: Vec<String>,
}
impl SseConnection {
#[must_use]
pub fn new() -> Self {
Self {
id: ConnectionId::new(),
user_id: None,
client_ip: None,
last_event_id: None,
subscribed_channels: Vec::new(),
}
}
#[must_use]
pub fn authenticated(user_id: impl Into<String>) -> Self {
Self {
id: ConnectionId::new(),
user_id: Some(user_id.into()),
client_ip: None,
last_event_id: None,
subscribed_channels: Vec::new(),
}
}
#[must_use]
pub fn with_client_ip(mut self, ip: impl Into<String>) -> Self {
self.client_ip = Some(ip.into());
self
}
#[must_use]
pub fn with_last_event_id(mut self, id: impl Into<String>) -> Self {
self.last_event_id = Some(id.into());
self
}
#[must_use]
pub fn with_channel(mut self, channel: impl Into<String>) -> Self {
self.subscribed_channels.push(channel.into());
self
}
#[must_use]
pub fn is_subscribed(&self, channel: &str) -> bool {
self.subscribed_channels.iter().any(|c| c == channel)
}
}
impl Default for SseConnection {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_connection_id() {
let id1 = ConnectionId::new();
let id2 = ConnectionId::new();
assert_ne!(id1, id2);
}
#[test]
fn test_sse_connection_builder() {
let conn = SseConnection::authenticated("user123")
.with_client_ip("192.168.1.1")
.with_last_event_id("event-42")
.with_channel("notifications");
assert_eq!(conn.user_id, Some("user123".to_string()));
assert_eq!(conn.client_ip, Some("192.168.1.1".to_string()));
assert_eq!(conn.last_event_id, Some("event-42".to_string()));
assert!(conn.is_subscribed("notifications"));
assert!(!conn.is_subscribed("other"));
}
}