pjson_rs/application/dto/
session_id_dto.rs

1//! SessionId Data Transfer Object for serialization
2//!
3//! Handles serialization/deserialization of SessionId domain objects
4//! while keeping domain layer clean of serialization concerns.
5
6use crate::{
7    application::dto::priority_dto::{FromDto, ToDto},
8    domain::{DomainError, value_objects::SessionId},
9};
10use serde::{Deserialize, Serialize};
11use uuid::Uuid;
12
13/// Serializable representation of SessionId domain object
14#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
15#[serde(transparent)]
16pub struct SessionIdDto {
17    uuid: Uuid,
18}
19
20impl SessionIdDto {
21    /// Create from UUID
22    pub fn new(uuid: Uuid) -> Self {
23        Self { uuid }
24    }
25
26    /// Create from string with validation
27    pub fn from_string(s: &str) -> Result<Self, uuid::Error> {
28        let uuid = Uuid::parse_str(s)?;
29        Ok(Self { uuid })
30    }
31
32    /// Get UUID value
33    pub fn uuid(self) -> Uuid {
34        self.uuid
35    }
36
37    /// Get string representation
38    pub fn as_string(self) -> String {
39        self.uuid.to_string()
40    }
41}
42
43impl From<SessionId> for SessionIdDto {
44    fn from(session_id: SessionId) -> Self {
45        Self {
46            uuid: session_id.as_uuid(),
47        }
48    }
49}
50
51impl From<SessionIdDto> for SessionId {
52    fn from(dto: SessionIdDto) -> Self {
53        SessionId::from_uuid(dto.uuid)
54    }
55}
56
57/// Utility trait implementation for SessionId
58impl ToDto<SessionIdDto> for SessionId {
59    fn to_dto(self) -> SessionIdDto {
60        SessionIdDto::from(self)
61    }
62}
63
64/// Utility trait implementation for SessionId
65impl FromDto<SessionIdDto> for SessionId {
66    type Error = DomainError;
67
68    fn from_dto(dto: SessionIdDto) -> Result<Self, Self::Error> {
69        Ok(SessionId::from(dto))
70    }
71}
72
73impl std::fmt::Display for SessionIdDto {
74    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75        write!(f, "{}", self.uuid)
76    }
77}
78
79#[cfg(test)]
80mod tests {
81    use super::*;
82    use serde_json;
83
84    #[test]
85    fn test_session_id_dto_serialization() {
86        let session_id = SessionId::new();
87        let dto = SessionIdDto::from(session_id);
88
89        // Test JSON serialization
90        let json = serde_json::to_string(&dto).unwrap();
91
92        // Test JSON deserialization
93        let deserialized: SessionIdDto = serde_json::from_str(&json).unwrap();
94        assert_eq!(deserialized.uuid(), dto.uuid());
95
96        // Test conversion back to domain
97        let domain_session_id = SessionId::from_dto(deserialized).unwrap();
98        assert_eq!(domain_session_id.as_uuid(), session_id.as_uuid());
99    }
100
101    #[test]
102    fn test_session_id_dto_from_string() {
103        let uuid_str = "550e8400-e29b-41d4-a716-446655440000";
104        let dto = SessionIdDto::from_string(uuid_str).unwrap();
105        assert_eq!(dto.as_string(), uuid_str);
106
107        // Test invalid UUID
108        assert!(SessionIdDto::from_string("invalid-uuid").is_err());
109    }
110
111    #[test]
112    fn test_conversion_traits() {
113        let session_id = SessionId::new();
114
115        // Test ToDto trait
116        let dto = session_id.to_dto();
117        assert_eq!(dto.uuid(), session_id.as_uuid());
118
119        // Test FromDto trait
120        let converted = SessionId::from_dto(dto).unwrap();
121        assert_eq!(converted.as_uuid(), session_id.as_uuid());
122    }
123}