pjson_rs/application/dto/
json_path_dto.rs1use crate::{
7 application::dto::priority_dto::{FromDto, ToDto},
8 domain::{DomainError, DomainResult, value_objects::JsonPath},
9};
10use serde::{Deserialize, Serialize};
11
12#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
14#[serde(transparent)]
15pub struct JsonPathDto {
16 path: String,
17}
18
19impl JsonPathDto {
20 pub fn new(path: impl Into<String>) -> DomainResult<Self> {
22 let path = path.into();
23 JsonPath::new(&path)?;
25 Ok(Self { path })
26 }
27
28 pub fn root() -> Self {
30 Self {
31 path: "$".to_string(),
32 }
33 }
34
35 pub fn path(&self) -> &str {
37 &self.path
38 }
39
40 pub fn into_path(self) -> String {
42 self.path
43 }
44}
45
46impl From<JsonPath> for JsonPathDto {
47 fn from(json_path: JsonPath) -> Self {
48 Self {
49 path: json_path.as_str().to_string(),
50 }
51 }
52}
53
54impl TryFrom<JsonPathDto> for JsonPath {
55 type Error = DomainError;
56
57 fn try_from(dto: JsonPathDto) -> Result<Self, Self::Error> {
58 JsonPath::new(dto.path)
59 }
60}
61
62impl ToDto<JsonPathDto> for JsonPath {
64 fn to_dto(self) -> JsonPathDto {
65 JsonPathDto::from(self)
66 }
67}
68
69impl FromDto<JsonPathDto> for JsonPath {
71 type Error = DomainError;
72
73 fn from_dto(dto: JsonPathDto) -> Result<Self, Self::Error> {
74 JsonPath::try_from(dto)
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81 use serde_json;
82
83 #[test]
84 fn test_json_path_dto_serialization() {
85 let json_path = JsonPath::new("$.users[0].name").unwrap();
86 let dto = JsonPathDto::from(json_path);
87
88 let json = serde_json::to_string(&dto).unwrap();
90 assert_eq!(json, "\"$.users[0].name\"");
91
92 let deserialized: JsonPathDto = serde_json::from_str(&json).unwrap();
94 assert_eq!(deserialized.path(), "$.users[0].name");
95
96 let domain_path = JsonPath::from_dto(deserialized).unwrap();
98 assert_eq!(domain_path.as_str(), "$.users[0].name");
99 }
100
101 #[test]
102 fn test_json_path_dto_validation() {
103 assert!(JsonPathDto::new("$.valid.path").is_ok());
105
106 assert!(JsonPathDto::new("invalid.path").is_err());
108 assert!(JsonPathDto::new("$.").is_err());
109 }
110
111 #[test]
112 fn test_json_path_dto_root() {
113 let root_dto = JsonPathDto::root();
114 assert_eq!(root_dto.path(), "$");
115
116 let domain_root = JsonPath::from_dto(root_dto).unwrap();
117 assert_eq!(domain_root, JsonPath::root());
118 }
119
120 #[test]
121 fn test_conversion_traits() {
122 let json_path = JsonPath::new("$.test.path").unwrap();
123
124 let dto = json_path.to_dto();
126 assert_eq!(dto.path(), "$.test.path");
127
128 let converted = JsonPath::from_dto(dto).unwrap();
130 assert_eq!(converted.as_str(), "$.test.path");
131 }
132
133 #[test]
134 fn test_json_path_dto_edge_cases() {
135 let paths = vec![
136 "$",
137 "$.key",
138 "$.array[0]",
139 "$.nested.deep.path",
140 "$.array[123].field",
141 ];
142
143 for path in paths {
144 let original = JsonPath::new(path).unwrap();
145 let original_str = original.as_str().to_string(); let dto = original.to_dto();
147 let serialized = serde_json::to_string(&dto).unwrap();
148 let deserialized: JsonPathDto = serde_json::from_str(&serialized).unwrap();
149 let restored = JsonPath::from_dto(deserialized).unwrap();
150
151 assert_eq!(original_str, restored.as_str());
152 }
153 }
154}