1use crate::error::PickError;
2use serde_json::Value;
3use super::types::Segment;
4
5pub fn apply_set(value: &Value, segments: &[Segment], new_value: &Value) -> Result<Value, PickError> {
11 if segments.is_empty() {
12 return Ok(new_value.clone());
13 }
14
15 let segment = &segments[0];
16 let rest = &segments[1..];
17
18 if let Some(ref key) = segment.key {
19 match value {
21 Value::Object(map) => {
22 let mut new_map = map.clone();
23 let child = map.get(key).unwrap_or(&Value::Null);
24 let child = apply_set_with_indices(child, &segment.indices, rest, new_value)?;
25 new_map.insert(key.clone(), child);
26 Ok(Value::Object(new_map))
27 }
28 _ => {
30 let mut new_map = serde_json::Map::new();
31 let child = apply_set_with_indices(&Value::Null, &segment.indices, rest, new_value)?;
32 new_map.insert(key.clone(), child);
33 Ok(Value::Object(new_map))
34 }
35 }
36 } else {
37 apply_set_with_indices(value, &segment.indices, rest, new_value)
39 }
40}
41
42fn apply_set_with_indices(
43 value: &Value,
44 indices: &[super::types::Index],
45 remaining_segments: &[Segment],
46 new_value: &Value,
47) -> Result<Value, PickError> {
48 if indices.is_empty() {
49 return apply_set(value, remaining_segments, new_value);
50 }
51
52 let index = &indices[0];
53 let rest_indices = &indices[1..];
54
55 match index {
56 super::types::Index::Number(n) => {
57 match value {
58 Value::Array(arr) => {
59 let len = arr.len();
60 let i = resolve_index(*n, len)?;
61 let mut new_arr = arr.clone();
62 if i < len {
63 let child = &arr[i];
64 new_arr[i] = apply_set_with_indices(child, rest_indices, remaining_segments, new_value)?;
65 }
66 Ok(Value::Array(new_arr))
67 }
68 _ => Err(PickError::NotAnArray(
69 super::extract::value_type_name(value).into(),
70 )),
71 }
72 }
73 _ => Err(PickError::InvalidSelector(
75 "set() does not support wildcard or slice indices".into(),
76 )),
77 }
78}
79
80pub fn apply_del(value: &Value, segments: &[Segment]) -> Result<Value, PickError> {
85 if segments.is_empty() {
86 return Ok(Value::Null);
88 }
89
90 let segment = &segments[0];
91 let rest = &segments[1..];
92
93 if let Some(ref key) = segment.key {
94 match value {
95 Value::Object(map) => {
96 if rest.is_empty() && segment.indices.is_empty() {
97 let mut new_map = map.clone();
99 new_map.remove(key);
100 Ok(Value::Object(new_map))
101 } else if let Some(child) = map.get(key) {
102 let mut new_map = map.clone();
104 let new_child = apply_del_with_indices(child, &segment.indices, rest)?;
105 new_map.insert(key.clone(), new_child);
106 Ok(Value::Object(new_map))
107 } else {
108 Ok(value.clone())
110 }
111 }
112 _ => Ok(value.clone()), }
114 } else {
115 apply_del_with_indices(value, &segment.indices, rest)
117 }
118}
119
120fn apply_del_with_indices(
121 value: &Value,
122 indices: &[super::types::Index],
123 remaining_segments: &[Segment],
124) -> Result<Value, PickError> {
125 if indices.is_empty() {
126 return apply_del(value, remaining_segments);
127 }
128
129 let index = &indices[0];
130 let rest_indices = &indices[1..];
131
132 match index {
133 super::types::Index::Number(n) => {
134 match value {
135 Value::Array(arr) => {
136 let len = arr.len();
137 let i = resolve_index(*n, len)?;
138 if i >= len {
139 return Ok(value.clone()); }
141
142 if rest_indices.is_empty() && remaining_segments.is_empty() {
143 let mut new_arr = arr.clone();
145 new_arr.remove(i);
146 Ok(Value::Array(new_arr))
147 } else {
148 let mut new_arr = arr.clone();
150 new_arr[i] = apply_del_with_indices(&arr[i], rest_indices, remaining_segments)?;
151 Ok(Value::Array(new_arr))
152 }
153 }
154 _ => Ok(value.clone()), }
156 }
157 _ => Err(PickError::InvalidSelector(
158 "del() does not support wildcard or slice indices".into(),
159 )),
160 }
161}
162
163fn resolve_index(n: i64, len: usize) -> Result<usize, PickError> {
164 if n < 0 {
165 let len_i64 = len as i64;
166 if n.unsigned_abs() > len as u64 {
167 return Err(PickError::IndexOutOfBounds(n));
168 }
169 Ok((len_i64 + n) as usize)
170 } else {
171 Ok(n as usize)
172 }
173}
174
175#[cfg(test)]
176mod tests {
177 use super::*;
178 use crate::selector::types::Selector;
179 use serde_json::json;
180
181 #[test]
184 fn set_top_level_key() {
185 let val = json!({"a": 1, "b": 2});
186 let sel = Selector::parse("a").unwrap();
187 let result = apply_set(&val, &sel.segments, &json!(99)).unwrap();
188 assert_eq!(result, json!({"a": 99, "b": 2}));
189 }
190
191 #[test]
192 fn set_nested_key() {
193 let val = json!({"x": {"y": 1}});
194 let sel = Selector::parse("x.y").unwrap();
195 let result = apply_set(&val, &sel.segments, &json!(2)).unwrap();
196 assert_eq!(result, json!({"x": {"y": 2}}));
197 }
198
199 #[test]
200 fn set_new_key() {
201 let val = json!({"a": 1});
202 let sel = Selector::parse("b").unwrap();
203 let result = apply_set(&val, &sel.segments, &json!(2)).unwrap();
204 assert_eq!(result["a"], json!(1));
205 assert_eq!(result["b"], json!(2));
206 }
207
208 #[test]
209 fn set_deep_new_path() {
210 let val = json!({});
211 let sel = Selector::parse("a.b").unwrap();
212 let result = apply_set(&val, &sel.segments, &json!(1)).unwrap();
213 assert_eq!(result, json!({"a": {"b": 1}}));
214 }
215
216 #[test]
217 fn set_array_element() {
218 let val = json!({"items": [1, 2, 3]});
219 let sel = Selector::parse("items[1]").unwrap();
220 let result = apply_set(&val, &sel.segments, &json!(99)).unwrap();
221 assert_eq!(result, json!({"items": [1, 99, 3]}));
222 }
223
224 #[test]
225 fn set_array_negative_index() {
226 let val = json!({"items": [1, 2, 3]});
227 let sel = Selector::parse("items[-1]").unwrap();
228 let result = apply_set(&val, &sel.segments, &json!(99)).unwrap();
229 assert_eq!(result, json!({"items": [1, 2, 99]}));
230 }
231
232 #[test]
233 fn set_nested_in_array() {
234 let val = json!({"users": [{"name": "Alice"}, {"name": "Bob"}]});
235 let sel = Selector::parse("users[0].name").unwrap();
236 let result = apply_set(&val, &sel.segments, &json!("Charlie")).unwrap();
237 assert_eq!(result["users"][0]["name"], json!("Charlie"));
238 assert_eq!(result["users"][1]["name"], json!("Bob"));
239 }
240
241 #[test]
242 fn set_string_value() {
243 let val = json!({"name": "old"});
244 let sel = Selector::parse("name").unwrap();
245 let result = apply_set(&val, &sel.segments, &json!("new")).unwrap();
246 assert_eq!(result, json!({"name": "new"}));
247 }
248
249 #[test]
250 fn set_null_value() {
251 let val = json!({"x": 1});
252 let sel = Selector::parse("x").unwrap();
253 let result = apply_set(&val, &sel.segments, &json!(null)).unwrap();
254 assert_eq!(result, json!({"x": null}));
255 }
256
257 #[test]
258 fn set_bool_value() {
259 let val = json!({"active": false});
260 let sel = Selector::parse("active").unwrap();
261 let result = apply_set(&val, &sel.segments, &json!(true)).unwrap();
262 assert_eq!(result, json!({"active": true}));
263 }
264
265 #[test]
266 fn set_empty_path_replaces_root() {
267 let val = json!({"a": 1});
268 let result = apply_set(&val, &[], &json!(42)).unwrap();
269 assert_eq!(result, json!(42));
270 }
271
272 #[test]
275 fn del_top_level_key() {
276 let val = json!({"a": 1, "b": 2});
277 let sel = Selector::parse("a").unwrap();
278 let result = apply_del(&val, &sel.segments).unwrap();
279 assert_eq!(result, json!({"b": 2}));
280 }
281
282 #[test]
283 fn del_nested_key() {
284 let val = json!({"x": {"y": 1, "z": 2}});
285 let sel = Selector::parse("x.y").unwrap();
286 let result = apply_del(&val, &sel.segments).unwrap();
287 assert_eq!(result, json!({"x": {"z": 2}}));
288 }
289
290 #[test]
291 fn del_missing_key() {
292 let val = json!({"a": 1});
293 let sel = Selector::parse("missing").unwrap();
294 let result = apply_del(&val, &sel.segments).unwrap();
295 assert_eq!(result, json!({"a": 1}));
296 }
297
298 #[test]
299 fn del_array_element() {
300 let val = json!({"items": [1, 2, 3]});
301 let sel = Selector::parse("items[1]").unwrap();
302 let result = apply_del(&val, &sel.segments).unwrap();
303 assert_eq!(result, json!({"items": [1, 3]}));
304 }
305
306 #[test]
307 fn del_array_first() {
308 let val = json!({"items": [1, 2, 3]});
309 let sel = Selector::parse("items[0]").unwrap();
310 let result = apply_del(&val, &sel.segments).unwrap();
311 assert_eq!(result, json!({"items": [2, 3]}));
312 }
313
314 #[test]
315 fn del_array_last_negative() {
316 let val = json!({"items": [1, 2, 3]});
317 let sel = Selector::parse("items[-1]").unwrap();
318 let result = apply_del(&val, &sel.segments).unwrap();
319 assert_eq!(result, json!({"items": [1, 2]}));
320 }
321
322 #[test]
323 fn del_nested_in_array() {
324 let val = json!({"users": [{"name": "Alice", "temp": "x"}, {"name": "Bob"}]});
325 let sel = Selector::parse("users[0].temp").unwrap();
326 let result = apply_del(&val, &sel.segments).unwrap();
327 assert_eq!(result["users"][0], json!({"name": "Alice"}));
328 assert_eq!(result["users"][1], json!({"name": "Bob"}));
329 }
330
331 #[test]
332 fn del_from_non_object_noop() {
333 let val = json!("hello");
334 let sel = Selector::parse("foo").unwrap();
335 let result = apply_del(&val, &sel.segments).unwrap();
336 assert_eq!(result, json!("hello"));
337 }
338
339 #[test]
340 fn del_empty_path_returns_null() {
341 let val = json!({"a": 1});
342 let result = apply_del(&val, &[]).unwrap();
343 assert_eq!(result, json!(null));
344 }
345
346 #[test]
347 fn del_preserves_other_keys() {
348 let val = json!({"a": 1, "b": 2, "c": 3});
349 let sel = Selector::parse("b").unwrap();
350 let result = apply_del(&val, &sel.segments).unwrap();
351 assert_eq!(result["a"], json!(1));
352 assert_eq!(result["c"], json!(3));
353 assert!(result.get("b").is_none());
354 }
355
356 #[test]
363 fn set_triple_nested_creates_intermediates() {
364 let val = json!({});
365 let sel = Selector::parse("a.b.c").unwrap();
366 let result = apply_set(&val, &sel.segments, &json!(42)).unwrap();
367 assert_eq!(result, json!({"a": {"b": {"c": 42}}}));
368 }
369
370 #[test]
371 fn set_deep_new_path_four_levels() {
372 let val = json!({});
373 let sel = Selector::parse("a.b.c.d").unwrap();
374 let result = apply_set(&val, &sel.segments, &json!("deep")).unwrap();
375 assert_eq!(result["a"]["b"]["c"]["d"], json!("deep"));
376 }
377
378 #[test]
379 fn set_overwrites_non_object_with_object() {
380 let val = json!({"a": "string"});
382 let sel = Selector::parse("a.b").unwrap();
383 let result = apply_set(&val, &sel.segments, &json!(1)).unwrap();
384 assert_eq!(result, json!({"a": {"b": 1}}));
385 }
386
387 #[test]
388 fn set_on_root_number() {
389 let val = json!(42);
390 let sel = Selector::parse("a").unwrap();
391 let result = apply_set(&val, &sel.segments, &json!(1)).unwrap();
392 assert_eq!(result, json!({"a": 1}));
393 }
394
395 #[test]
396 fn set_preserves_sibling_keys() {
397 let val = json!({"x": {"a": 1, "b": 2, "c": 3}});
398 let sel = Selector::parse("x.b").unwrap();
399 let result = apply_set(&val, &sel.segments, &json!(99)).unwrap();
400 assert_eq!(result["x"]["a"], json!(1));
401 assert_eq!(result["x"]["b"], json!(99));
402 assert_eq!(result["x"]["c"], json!(3));
403 }
404
405 #[test]
406 fn set_array_first_element() {
407 let val = json!({"items": [10, 20, 30]});
408 let sel = Selector::parse("items[0]").unwrap();
409 let result = apply_set(&val, &sel.segments, &json!(99)).unwrap();
410 assert_eq!(result, json!({"items": [99, 20, 30]}));
411 }
412
413 #[test]
414 fn set_array_middle_element() {
415 let val = json!([1, 2, 3, 4, 5]);
416 let sel = Selector::parse("[2]").unwrap();
417 let result = apply_set(&val, &sel.segments, &json!(99)).unwrap();
418 assert_eq!(result, json!([1, 2, 99, 4, 5]));
419 }
420
421 #[test]
422 fn set_nested_array_in_object() {
423 let val = json!({"data": {"items": [1, 2, 3]}});
424 let sel = Selector::parse("data.items[1]").unwrap();
425 let result = apply_set(&val, &sel.segments, &json!(99)).unwrap();
426 assert_eq!(result["data"]["items"], json!([1, 99, 3]));
427 }
428
429 #[test]
430 fn set_with_negative_index_middle() {
431 let val = json!([10, 20, 30, 40]);
432 let sel = Selector::parse("[-2]").unwrap();
433 let result = apply_set(&val, &sel.segments, &json!(99)).unwrap();
434 assert_eq!(result, json!([10, 20, 99, 40]));
435 }
436
437 #[test]
438 fn set_wildcard_error() {
439 let val = json!({"items": [1, 2, 3]});
440 let sel = Selector::parse("items[*]").unwrap();
441 assert!(apply_set(&val, &sel.segments, &json!(0)).is_err());
442 }
443
444 #[test]
445 fn set_slice_error() {
446 let val = json!({"items": [1, 2, 3]});
447 let sel = Selector::parse("items[0:2]").unwrap();
448 assert!(apply_set(&val, &sel.segments, &json!(0)).is_err());
449 }
450
451 #[test]
452 fn set_object_value() {
453 let val = json!({"config": {}});
454 let sel = Selector::parse("config.server").unwrap();
455 let result = apply_set(&val, &sel.segments, &json!({"host": "localhost", "port": 8080})).unwrap();
456 assert_eq!(result["config"]["server"]["host"], json!("localhost"));
457 }
458
459 #[test]
460 fn set_array_value() {
461 let val = json!({"data": {}});
462 let sel = Selector::parse("data.items").unwrap();
463 let result = apply_set(&val, &sel.segments, &json!([1, 2, 3])).unwrap();
464 assert_eq!(result["data"]["items"], json!([1, 2, 3]));
465 }
466
467 #[test]
470 fn del_deeply_nested_missing_intermediate() {
471 let val = json!({"a": 1});
473 let sel = Selector::parse("a.b.c").unwrap();
474 let result = apply_del(&val, &sel.segments).unwrap();
475 assert_eq!(result, json!({"a": 1}));
477 }
478
479 #[test]
480 fn del_deeply_nested_key() {
481 let val = json!({"a": {"b": {"c": 1, "d": 2}}});
482 let sel = Selector::parse("a.b.c").unwrap();
483 let result = apply_del(&val, &sel.segments).unwrap();
484 assert_eq!(result, json!({"a": {"b": {"d": 2}}}));
485 }
486
487 #[test]
488 fn del_array_last_element() {
489 let val = json!([1, 2, 3]);
490 let sel = Selector::parse("[2]").unwrap();
491 let result = apply_del(&val, &sel.segments).unwrap();
492 assert_eq!(result, json!([1, 2]));
493 }
494
495 #[test]
496 fn del_array_out_of_bounds_noop() {
497 let val = json!({"items": [1, 2, 3]});
499 let sel = Selector::parse("items[10]").unwrap();
500 let result = apply_del(&val, &sel.segments).unwrap();
501 assert_eq!(result, json!({"items": [1, 2, 3]}));
502 }
503
504 #[test]
505 fn del_negative_index_first() {
506 let val = json!([10, 20, 30]);
507 let sel = Selector::parse("[-3]").unwrap();
508 let result = apply_del(&val, &sel.segments).unwrap();
509 assert_eq!(result, json!([20, 30]));
510 }
511
512 #[test]
513 fn del_all_keys_one_by_one() {
514 let val = json!({"a": 1});
515 let sel = Selector::parse("a").unwrap();
516 let result = apply_del(&val, &sel.segments).unwrap();
517 assert_eq!(result, json!({}));
518 }
519
520 #[test]
521 fn del_from_array_non_array_noop() {
522 let val = json!({"items": "not an array"});
523 let sel = Selector::parse("items[0]").unwrap();
524 let result = apply_del(&val, &sel.segments).unwrap();
526 assert_eq!(result["items"], json!("not an array"));
528 }
529
530 #[test]
531 fn del_wildcard_error() {
532 let val = json!({"items": [1, 2, 3]});
533 let sel = Selector::parse("items[*]").unwrap();
534 assert!(apply_del(&val, &sel.segments).is_err());
535 }
536
537 #[test]
538 fn del_slice_error() {
539 let val = json!({"items": [1, 2, 3]});
540 let sel = Selector::parse("items[0:2]").unwrap();
541 assert!(apply_del(&val, &sel.segments).is_err());
542 }
543
544 #[test]
545 fn del_nested_in_array_preserves_siblings() {
546 let val = json!([
547 {"name": "Alice", "age": 30, "temp": "x"},
548 {"name": "Bob", "age": 25}
549 ]);
550 let sel = Selector::parse("[0].temp").unwrap();
551 let result = apply_del(&val, &sel.segments).unwrap();
552 assert_eq!(result[0], json!({"name": "Alice", "age": 30}));
553 assert_eq!(result[1], json!({"name": "Bob", "age": 25}));
554 }
555
556 #[test]
557 fn del_single_element_array() {
558 let val = json!([42]);
559 let sel = Selector::parse("[0]").unwrap();
560 let result = apply_del(&val, &sel.segments).unwrap();
561 assert_eq!(result, json!([]));
562 }
563
564 #[test]
567 fn resolve_positive_index() {
568 assert_eq!(resolve_index(0, 5).unwrap(), 0);
569 assert_eq!(resolve_index(4, 5).unwrap(), 4);
570 }
571
572 #[test]
573 fn resolve_negative_index() {
574 assert_eq!(resolve_index(-1, 5).unwrap(), 4);
575 assert_eq!(resolve_index(-5, 5).unwrap(), 0);
576 }
577
578 #[test]
579 fn resolve_negative_out_of_bounds() {
580 assert!(resolve_index(-6, 5).is_err());
581 }
582}