use crate::{
application::dto::priority_dto::{FromDto, ToDto},
domain::{DomainError, DomainResult, value_objects::JsonPath},
};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct JsonPathDto {
path: String,
}
impl JsonPathDto {
pub fn new(path: impl Into<String>) -> DomainResult<Self> {
let path = path.into();
JsonPath::new(&path)?;
Ok(Self { path })
}
pub fn root() -> Self {
Self {
path: "$".to_string(),
}
}
pub fn path(&self) -> &str {
&self.path
}
pub fn into_path(self) -> String {
self.path
}
}
impl From<JsonPath> for JsonPathDto {
fn from(json_path: JsonPath) -> Self {
Self {
path: json_path.as_str().to_string(),
}
}
}
impl TryFrom<JsonPathDto> for JsonPath {
type Error = DomainError;
fn try_from(dto: JsonPathDto) -> Result<Self, Self::Error> {
JsonPath::new(dto.path)
}
}
impl ToDto<JsonPathDto> for JsonPath {
fn to_dto(self) -> JsonPathDto {
JsonPathDto::from(self)
}
}
impl FromDto<JsonPathDto> for JsonPath {
type Error = DomainError;
fn from_dto(dto: JsonPathDto) -> Result<Self, Self::Error> {
JsonPath::try_from(dto)
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json;
#[test]
fn test_json_path_dto_serialization() {
let json_path = JsonPath::new("$.users[0].name").unwrap();
let dto = JsonPathDto::from(json_path);
let json = serde_json::to_string(&dto).unwrap();
assert_eq!(json, "\"$.users[0].name\"");
let deserialized: JsonPathDto = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.path(), "$.users[0].name");
let domain_path = JsonPath::from_dto(deserialized).unwrap();
assert_eq!(domain_path.as_str(), "$.users[0].name");
}
#[test]
fn test_json_path_dto_validation() {
assert!(JsonPathDto::new("$.valid.path").is_ok());
assert!(JsonPathDto::new("invalid.path").is_err());
assert!(JsonPathDto::new("$.").is_err());
}
#[test]
fn test_json_path_dto_root() {
let root_dto = JsonPathDto::root();
assert_eq!(root_dto.path(), "$");
let domain_root = JsonPath::from_dto(root_dto).unwrap();
assert_eq!(domain_root, JsonPath::root());
}
#[test]
fn test_conversion_traits() {
let json_path = JsonPath::new("$.test.path").unwrap();
let dto = json_path.to_dto();
assert_eq!(dto.path(), "$.test.path");
let converted = JsonPath::from_dto(dto).unwrap();
assert_eq!(converted.as_str(), "$.test.path");
}
#[test]
fn test_json_path_dto_edge_cases() {
let paths = vec![
"$",
"$.key",
"$.array[0]",
"$.nested.deep.path",
"$.array[123].field",
];
for path in paths {
let original = JsonPath::new(path).unwrap();
let original_str = original.as_str().to_string(); let dto = original.to_dto();
let serialized = serde_json::to_string(&dto).unwrap();
let deserialized: JsonPathDto = serde_json::from_str(&serialized).unwrap();
let restored = JsonPath::from_dto(deserialized).unwrap();
assert_eq!(original_str, restored.as_str());
}
}
}