use crate::domain::value_objects::Priority;
use crate::domain::{DomainError, DomainResult};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct PriorityDto {
value: u8,
}
impl PriorityDto {
pub fn new(value: u8) -> DomainResult<Self> {
Priority::new(value)?;
Ok(Self { value })
}
pub fn value(self) -> u8 {
self.value
}
}
impl From<Priority> for PriorityDto {
fn from(priority: Priority) -> Self {
Self {
value: priority.value(),
}
}
}
impl TryFrom<PriorityDto> for Priority {
type Error = DomainError;
fn try_from(dto: PriorityDto) -> Result<Self, Self::Error> {
Priority::new(dto.value)
}
}
pub trait ToDto<T> {
fn to_dto(self) -> T;
}
impl ToDto<PriorityDto> for Priority {
fn to_dto(self) -> PriorityDto {
PriorityDto::from(self)
}
}
pub trait FromDto<T> {
type Error;
fn from_dto(dto: T) -> Result<Self, Self::Error>
where
Self: Sized;
}
impl FromDto<PriorityDto> for Priority {
type Error = DomainError;
fn from_dto(dto: PriorityDto) -> Result<Self, Self::Error> {
Priority::try_from(dto)
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json;
#[test]
fn test_priority_dto_serialization() {
let priority = Priority::CRITICAL;
let dto = PriorityDto::from(priority);
let json = serde_json::to_string(&dto).unwrap();
assert_eq!(json, "100");
let deserialized: PriorityDto = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.value(), 100);
let domain_priority = Priority::from_dto(deserialized).unwrap();
assert_eq!(domain_priority, Priority::CRITICAL);
}
#[test]
fn test_priority_dto_validation() {
assert!(PriorityDto::new(100).is_ok());
assert!(PriorityDto::new(0).is_err());
}
#[test]
fn test_conversion_traits() {
let priority = Priority::HIGH;
let dto = priority.to_dto();
assert_eq!(dto.value(), 80);
let converted = Priority::from_dto(dto).unwrap();
assert_eq!(converted, Priority::HIGH);
}
}