1use serde::{Deserialize, Serialize};
7use serde_json::Value;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
26pub struct EvalRequest {
27 pub expression: String,
29 pub input: Value,
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct EvalResponse {
38 pub result: Value,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
63pub struct ValidationResult {
64 pub valid: bool,
66 #[serde(skip_serializing_if = "Option::is_none")]
68 pub error: Option<String>,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct BatchExpressionResult {
77 pub expression: String,
79 #[serde(skip_serializing_if = "Option::is_none")]
81 pub result: Option<Value>,
82 #[serde(skip_serializing_if = "Option::is_none")]
84 pub error: Option<String>,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
111pub struct BatchEvaluateResult {
112 pub results: Vec<BatchExpressionResult>,
114}
115
116#[cfg(test)]
117mod tests {
118 use super::*;
119 use serde_json::json;
120
121 #[test]
122 fn test_eval_request_serde_roundtrip() {
123 let request = EvalRequest {
124 expression: "users[*].name".to_string(),
125 input: json!({"users": [{"name": "alice"}]}),
126 };
127
128 let json_str = serde_json::to_string(&request).unwrap();
129 let deserialized: EvalRequest = serde_json::from_str(&json_str).unwrap();
130
131 assert_eq!(deserialized.expression, "users[*].name");
132 assert_eq!(deserialized.input, json!({"users": [{"name": "alice"}]}));
133 }
134
135 #[test]
136 fn test_eval_response_serde_roundtrip() {
137 let response = EvalResponse {
138 result: json!(["alice", "bob"]),
139 };
140
141 let json_str = serde_json::to_string(&response).unwrap();
142 let deserialized: EvalResponse = serde_json::from_str(&json_str).unwrap();
143
144 assert_eq!(deserialized.result, json!(["alice", "bob"]));
145 }
146
147 #[test]
148 fn test_validation_result_valid_roundtrip() {
149 let result = ValidationResult {
150 valid: true,
151 error: None,
152 };
153
154 let json_str = serde_json::to_string(&result).unwrap();
155 let deserialized: ValidationResult = serde_json::from_str(&json_str).unwrap();
156
157 assert!(deserialized.valid);
158 assert!(deserialized.error.is_none());
159 }
160
161 #[test]
162 fn test_validation_result_invalid_roundtrip() {
163 let result = ValidationResult {
164 valid: false,
165 error: Some("unexpected token".to_string()),
166 };
167
168 let json_str = serde_json::to_string(&result).unwrap();
169 let deserialized: ValidationResult = serde_json::from_str(&json_str).unwrap();
170
171 assert!(!deserialized.valid);
172 assert_eq!(deserialized.error.as_deref(), Some("unexpected token"));
173 }
174
175 #[test]
176 fn test_validation_result_skip_none_error() {
177 let result = ValidationResult {
178 valid: true,
179 error: None,
180 };
181
182 let json_str = serde_json::to_string(&result).unwrap();
183 let json_value: Value = serde_json::from_str(&json_str).unwrap();
184
185 assert!(json_value.get("error").is_none());
186 }
187
188 #[test]
189 fn test_batch_expression_result_success() {
190 let result = BatchExpressionResult {
191 expression: "a.b".to_string(),
192 result: Some(json!(42)),
193 error: None,
194 };
195
196 let json_str = serde_json::to_string(&result).unwrap();
197 let deserialized: BatchExpressionResult = serde_json::from_str(&json_str).unwrap();
198
199 assert_eq!(deserialized.expression, "a.b");
200 assert_eq!(deserialized.result, Some(json!(42)));
201 assert!(deserialized.error.is_none());
202 }
203
204 #[test]
205 fn test_batch_expression_result_error() {
206 let result = BatchExpressionResult {
207 expression: "invalid[".to_string(),
208 result: None,
209 error: Some("parse error".to_string()),
210 };
211
212 let json_str = serde_json::to_string(&result).unwrap();
213 let deserialized: BatchExpressionResult = serde_json::from_str(&json_str).unwrap();
214
215 assert_eq!(deserialized.expression, "invalid[");
216 assert!(deserialized.result.is_none());
217 assert_eq!(deserialized.error.as_deref(), Some("parse error"));
218 }
219
220 #[test]
221 fn test_batch_expression_result_skip_none_fields() {
222 let result = BatchExpressionResult {
223 expression: "a".to_string(),
224 result: Some(json!(1)),
225 error: None,
226 };
227
228 let json_str = serde_json::to_string(&result).unwrap();
229 let json_value: Value = serde_json::from_str(&json_str).unwrap();
230
231 assert!(json_value.get("expression").is_some());
232 assert!(json_value.get("result").is_some());
233 assert!(json_value.get("error").is_none());
234
235 let error_result = BatchExpressionResult {
236 expression: "bad".to_string(),
237 result: None,
238 error: Some("fail".to_string()),
239 };
240
241 let json_str = serde_json::to_string(&error_result).unwrap();
242 let json_value: Value = serde_json::from_str(&json_str).unwrap();
243
244 assert!(json_value.get("expression").is_some());
245 assert!(json_value.get("result").is_none());
246 assert!(json_value.get("error").is_some());
247 }
248
249 #[test]
250 fn test_batch_evaluate_result_roundtrip() {
251 let batch = BatchEvaluateResult {
252 results: vec![
253 BatchExpressionResult {
254 expression: "a".to_string(),
255 result: Some(json!(1)),
256 error: None,
257 },
258 BatchExpressionResult {
259 expression: "b".to_string(),
260 result: Some(json!(2)),
261 error: None,
262 },
263 BatchExpressionResult {
264 expression: "invalid[".to_string(),
265 result: None,
266 error: Some("parse error".to_string()),
267 },
268 ],
269 };
270
271 let json_str = serde_json::to_string(&batch).unwrap();
272 let deserialized: BatchEvaluateResult = serde_json::from_str(&json_str).unwrap();
273
274 assert_eq!(deserialized.results.len(), 3);
275 assert_eq!(deserialized.results[0].expression, "a");
276 assert_eq!(deserialized.results[0].result, Some(json!(1)));
277 assert_eq!(deserialized.results[1].expression, "b");
278 assert_eq!(deserialized.results[1].result, Some(json!(2)));
279 assert_eq!(deserialized.results[2].expression, "invalid[");
280 assert!(deserialized.results[2].result.is_none());
281 assert_eq!(
282 deserialized.results[2].error.as_deref(),
283 Some("parse error")
284 );
285 }
286
287 #[test]
288 fn test_eval_request_complex_input() {
289 let request = EvalRequest {
290 expression: "data.users[?age > `30`].name".to_string(),
291 input: json!({
292 "data": {
293 "users": [
294 {"name": "alice", "age": 25, "tags": ["admin", "user"]},
295 {"name": "bob", "age": 35, "tags": ["user"]},
296 {"name": "carol", "age": 40, "tags": []}
297 ],
298 "metadata": {
299 "count": 3,
300 "active": true,
301 "ratio": 0.75,
302 "nothing": null
303 }
304 }
305 }),
306 };
307
308 let json_str = serde_json::to_string(&request).unwrap();
309 let deserialized: EvalRequest = serde_json::from_str(&json_str).unwrap();
310
311 assert_eq!(deserialized.expression, "data.users[?age > `30`].name");
312 assert_eq!(deserialized.input, request.input);
313 assert_eq!(deserialized.input["data"]["users"][0]["name"], "alice");
314 assert_eq!(deserialized.input["data"]["metadata"]["count"], 3);
315 assert_eq!(deserialized.input["data"]["metadata"]["active"], true);
316 assert_eq!(deserialized.input["data"]["metadata"]["ratio"], 0.75);
317 assert!(deserialized.input["data"]["metadata"]["nothing"].is_null());
318 }
319}