1use crate::{Error, Value};
2use indexmap::IndexMap;
3use std::cmp::Ordering;
4use std::collections::BTreeMap;
5
6pub type ValueMap = Vec<(Value, Value)>;
7
8pub trait ValueMapHelper {
9 fn sort_by_keys(&mut self);
10 fn sort_by_keys_and_inner_maps(&mut self);
11 fn sort_by_lexicographical_byte_ordering_keys(&mut self);
12 fn sort_by_lexicographical_byte_ordering_keys_and_inner_maps(&mut self);
13 fn get_key(&self, search_key: &str) -> Result<&Value, Error>;
14 fn get_optional_key(&self, key: &str) -> Option<&Value>;
15 fn get_key_mut(&mut self, search_key: &str) -> Result<&mut Value, Error>;
16 fn get_optional_key_mut(&mut self, key: &str) -> Option<&mut Value>;
17 fn get_key_mut_or_insert(&mut self, key: &str, value: Value) -> &mut Value;
18 fn get_key_by_value_mut_or_insert(&mut self, search_key: &Value, value: Value) -> &mut Value;
19 fn insert_string_key_value(&mut self, key: String, value: Value);
20 fn remove_key(&mut self, search_key: &str) -> Result<Value, Error>;
21 fn remove_optional_key(&mut self, key: &str) -> Option<Value>;
22 fn remove_optional_key_if_null(&mut self, search_key: &str);
23 fn remove_optional_key_if_empty_array(&mut self, search_key: &str);
24 fn remove_optional_key_value(&mut self, search_key_value: &Value) -> Option<Value>;
25 fn from_btree_map<K: Into<Value> + Ord, V: Into<Value>>(btree_map: BTreeMap<K, V>) -> Self;
26}
27
28impl ValueMapHelper for ValueMap {
29 fn sort_by_keys(&mut self) {
30 self.sort_by(|(key1, _), (key2, _)| key1.partial_cmp(key2).unwrap_or(Ordering::Less));
31 }
32
33 fn sort_by_keys_and_inner_maps(&mut self) {
34 self.sort_by_keys();
35 self.iter_mut().for_each(|(_, v)| {
36 if let Value::Map(m) = v {
37 m.sort_by_keys_and_inner_maps()
38 }
39 });
40 }
41
42 fn sort_by_lexicographical_byte_ordering_keys(&mut self) {
43 self.sort_by(|(key1, _), (key2, _)| {
44 if key1.is_text() && key2.is_text() {
45 let key1 = key1.to_text().unwrap();
46 let key2 = key2.to_text().unwrap();
47 match key1.len().cmp(&key2.len()) {
48 Ordering::Less => Ordering::Less,
49 Ordering::Equal => key1.cmp(&key2),
50 Ordering::Greater => Ordering::Greater,
51 }
52 } else {
53 key1.partial_cmp(key2).unwrap_or(Ordering::Less)
54 }
55 })
56 }
57
58 fn sort_by_lexicographical_byte_ordering_keys_and_inner_maps(&mut self) {
59 self.sort_by_lexicographical_byte_ordering_keys();
60 self.iter_mut().for_each(|(_, v)| {
61 if let Value::Map(m) = v {
62 m.sort_by_lexicographical_byte_ordering_keys_and_inner_maps()
63 }
64 });
65 }
66
67 fn get_key(&self, search_key: &str) -> Result<&Value, Error> {
68 self.get_optional_key(search_key)
69 .ok_or(Error::StructureError(format!(
70 "required property not found {search_key}"
71 )))
72 }
73
74 fn get_optional_key(&self, search_key: &str) -> Option<&Value> {
75 self.iter().find_map(|(key, value)| {
76 if let Value::Text(text) = key {
77 if text == search_key {
78 Some(value)
79 } else {
80 None
81 }
82 } else {
83 None
84 }
85 })
86 }
87
88 fn get_key_mut(&mut self, search_key: &str) -> Result<&mut Value, Error> {
89 self.get_optional_key_mut(search_key)
90 .ok_or(Error::StructureError(format!(
91 "{search_key} not found, but was required"
92 )))
93 }
94
95 fn get_optional_key_mut(&mut self, search_key: &str) -> Option<&mut Value> {
96 self.iter_mut().find_map(|(key, value)| {
97 if let Value::Text(text) = key {
98 if text == search_key {
99 Some(value)
100 } else {
101 None
102 }
103 } else {
104 None
105 }
106 })
107 }
108
109 fn get_key_mut_or_insert(&mut self, search_key: &str, value: Value) -> &mut Value {
110 let found = self.iter().position(|(key, _)| {
111 if let Value::Text(text) = key {
112 text == search_key
113 } else {
114 false
115 }
116 });
117 match found {
118 None => {
119 self.push((Value::Text(search_key.to_string()), value));
120 let (_, value) = self.last_mut().unwrap();
121 value
122 }
123 Some(pos) => {
124 let (_, value) = self.get_mut(pos).unwrap();
125 value
126 }
127 }
128 }
129
130 fn get_key_by_value_mut_or_insert(&mut self, search_key: &Value, value: Value) -> &mut Value {
131 let found = self.iter().position(|(key, _)| search_key == key);
132 match found {
133 None => {
134 self.push((search_key.clone(), value));
135 let (_, value) = self.last_mut().unwrap();
136 value
137 }
138 Some(pos) => {
139 let (_, value) = self.get_mut(pos).unwrap();
140 value
141 }
142 }
143 }
144
145 fn insert_string_key_value(&mut self, key: String, value: Value) {
146 self.push((key.into(), value))
147 }
148
149 fn remove_key(&mut self, search_key: &str) -> Result<Value, Error> {
150 self.iter()
151 .position(|(key, _)| {
152 if let Value::Text(text) = key {
153 text == search_key
154 } else {
155 false
156 }
157 })
158 .map(|pos| self.remove(pos).1)
159 .ok_or(Error::StructureError(format!(
160 "trying to remove a key {} from a ValueMap that was not found",
161 search_key
162 )))
163 }
164
165 fn remove_optional_key(&mut self, search_key: &str) -> Option<Value> {
166 self.iter()
167 .position(|(key, _)| {
168 if let Value::Text(text) = key {
169 text == search_key
170 } else {
171 false
172 }
173 })
174 .map(|pos| self.remove(pos).1)
175 }
176
177 fn remove_optional_key_if_null(&mut self, search_key: &str) {
178 self.iter()
179 .position(|(key, value)| {
180 if let Value::Text(text) = key {
181 if text == search_key {
182 value.is_null()
183 } else {
184 false
185 }
186 } else {
187 false
188 }
189 })
190 .map(|pos| self.remove(pos).1);
191 }
192
193 fn remove_optional_key_if_empty_array(&mut self, search_key: &str) {
194 self.iter()
195 .position(|(key, value)| {
196 if let Value::Text(text) = key {
197 if text == search_key {
198 if let Some(v) = value.as_array() {
199 v.is_empty()
200 } else {
201 false
202 }
203 } else {
204 false
205 }
206 } else {
207 false
208 }
209 })
210 .map(|pos| self.remove(pos).1);
211 }
212
213 fn remove_optional_key_value(&mut self, search_key_value: &Value) -> Option<Value> {
214 self.iter()
215 .position(|(key, _)| search_key_value == key)
216 .map(|pos| self.remove(pos).1)
217 }
218 fn from_btree_map<K: Into<Value> + Ord, V: Into<Value>>(btree_map: BTreeMap<K, V>) -> Self {
219 btree_map
220 .into_iter()
221 .map(|(k, v)| (k.into(), v.into()))
222 .collect()
223 }
224}
225
226#[cfg(test)]
227mod tests {
228 use super::*;
229
230 fn text(s: &str) -> Value {
231 Value::Text(s.to_string())
232 }
233
234 fn make_map(pairs: &[(&str, Value)]) -> ValueMap {
235 pairs.iter().map(|(k, v)| (text(k), v.clone())).collect()
236 }
237
238 #[test]
243 fn sort_by_keys_mixed_text_keys() {
244 let mut map = make_map(&[
245 ("c", Value::U32(3)),
246 ("a", Value::U32(1)),
247 ("b", Value::U32(2)),
248 ]);
249 map.sort_by_keys();
250 let keys: Vec<_> = map.iter().map(|(k, _)| k.clone()).collect();
251 assert_eq!(keys, vec![text("a"), text("b"), text("c")]);
252 }
253
254 #[test]
255 fn sort_by_keys_mixed_types() {
256 let mut map: ValueMap = vec![
258 (text("z"), Value::U32(1)),
259 (Value::U32(5), Value::U32(2)),
260 (text("a"), Value::U32(3)),
261 ];
262 map.sort_by_keys();
263 assert_eq!(map[0].0, Value::U32(5));
265 assert_eq!(map[1].0, text("a"));
266 assert_eq!(map[2].0, text("z"));
267 }
268
269 #[test]
274 fn sort_by_lexicographical_byte_ordering_shorter_first() {
275 let mut map = make_map(&[
277 ("abc", Value::U32(1)),
278 ("ab", Value::U32(2)),
279 ("a", Value::U32(3)),
280 ]);
281 map.sort_by_lexicographical_byte_ordering_keys();
282 let keys: Vec<_> = map.iter().map(|(k, _)| k.to_text().unwrap()).collect();
283 assert_eq!(keys, vec!["a", "ab", "abc"]);
284 }
285
286 #[test]
287 fn sort_by_lexicographical_byte_ordering_same_length_alphabetical() {
288 let mut map = make_map(&[
289 ("cb", Value::U32(1)),
290 ("ab", Value::U32(2)),
291 ("bb", Value::U32(3)),
292 ]);
293 map.sort_by_lexicographical_byte_ordering_keys();
294 let keys: Vec<_> = map.iter().map(|(k, _)| k.to_text().unwrap()).collect();
295 assert_eq!(keys, vec!["ab", "bb", "cb"]);
296 }
297
298 #[test]
299 fn sort_by_lexicographical_byte_ordering_non_text_keys_uses_partial_cmp() {
300 let mut map: ValueMap = vec![(Value::U32(10), Value::Null), (Value::U32(2), Value::Null)];
301 map.sort_by_lexicographical_byte_ordering_keys();
302 assert_eq!(map[0].0, Value::U32(2));
303 assert_eq!(map[1].0, Value::U32(10));
304 }
305
306 #[test]
311 fn get_key_mut_or_insert_inserts_new() {
312 let mut map = make_map(&[("a", Value::U32(1))]);
313 let val = map.get_key_mut_or_insert("b", Value::U32(99));
314 assert_eq!(*val, Value::U32(99));
315 *val = Value::U32(100);
317 assert_eq!(map.get_optional_key("b"), Some(&Value::U32(100)));
318 }
319
320 #[test]
321 fn get_key_mut_or_insert_returns_existing() {
322 let mut map = make_map(&[("a", Value::U32(1))]);
323 let val = map.get_key_mut_or_insert("a", Value::U32(99));
324 assert_eq!(*val, Value::U32(1));
326 }
327
328 #[test]
329 fn get_key_mut_or_insert_existing_is_mutable() {
330 let mut map = make_map(&[("a", Value::U32(1))]);
331 let val = map.get_key_mut_or_insert("a", Value::U32(99));
332 *val = Value::U32(42);
333 assert_eq!(map.get_optional_key("a"), Some(&Value::U32(42)));
334 }
335
336 #[test]
341 fn remove_optional_key_if_null_removes_null() {
342 let mut map = make_map(&[("a", Value::Null), ("b", Value::U32(2))]);
343 map.remove_optional_key_if_null("a");
344 assert_eq!(map.get_optional_key("a"), None);
345 assert_eq!(map.get_optional_key("b"), Some(&Value::U32(2)));
346 }
347
348 #[test]
349 fn remove_optional_key_if_null_keeps_non_null() {
350 let mut map = make_map(&[("a", Value::U32(1))]);
351 map.remove_optional_key_if_null("a");
352 assert_eq!(map.get_optional_key("a"), Some(&Value::U32(1)));
353 }
354
355 #[test]
356 fn remove_optional_key_if_null_missing_key_is_noop() {
357 let mut map = make_map(&[("a", Value::U32(1))]);
358 map.remove_optional_key_if_null("missing");
359 assert_eq!(map.len(), 1);
360 }
361
362 #[test]
367 fn remove_optional_key_if_empty_array_removes_empty() {
368 let mut map = make_map(&[("a", Value::Array(vec![])), ("b", Value::U32(1))]);
369 map.remove_optional_key_if_empty_array("a");
370 assert_eq!(map.get_optional_key("a"), None);
371 assert_eq!(map.get_optional_key("b"), Some(&Value::U32(1)));
372 }
373
374 #[test]
375 fn remove_optional_key_if_empty_array_keeps_non_empty() {
376 let mut map = make_map(&[("a", Value::Array(vec![Value::U32(1)]))]);
377 map.remove_optional_key_if_empty_array("a");
378 assert!(map.get_optional_key("a").is_some());
379 }
380
381 #[test]
382 fn remove_optional_key_if_empty_array_keeps_non_array() {
383 let mut map = make_map(&[("a", Value::U32(42))]);
384 map.remove_optional_key_if_empty_array("a");
385 assert_eq!(map.get_optional_key("a"), Some(&Value::U32(42)));
386 }
387
388 #[test]
389 fn remove_optional_key_if_empty_array_missing_key_is_noop() {
390 let mut map = make_map(&[("a", Value::U32(1))]);
391 map.remove_optional_key_if_empty_array("missing");
392 assert_eq!(map.len(), 1);
393 }
394
395 #[test]
400 fn into_btree_string_map_valid_conversion() {
401 let val = Value::Map(make_map(&[("b", Value::U32(2)), ("a", Value::U32(1))]));
402 let btree = val.into_btree_string_map().unwrap();
403 assert_eq!(btree.get("a"), Some(&Value::U32(1)));
404 assert_eq!(btree.get("b"), Some(&Value::U32(2)));
405 let keys: Vec<_> = btree.keys().collect();
407 assert_eq!(keys, vec!["a", "b"]);
408 }
409
410 #[test]
411 fn into_btree_string_map_error_on_non_string_keys() {
412 let val = Value::Map(vec![(Value::U32(1), Value::U32(2))]);
413 let result = val.into_btree_string_map();
414 assert!(result.is_err());
415 }
416
417 #[test]
418 fn into_btree_string_map_error_on_non_map() {
419 let val = Value::Bool(true);
420 let result = val.into_btree_string_map();
421 assert!(result.is_err());
422 }
423
424 #[test]
429 fn map_ref_into_indexed_string_map_sorts_by_integer_key() {
430 let map: ValueMap = vec![
431 (
432 text("second"),
433 Value::Map(make_map(&[("pos", Value::U32(2))])),
434 ),
435 (
436 text("first"),
437 Value::Map(make_map(&[("pos", Value::U32(1))])),
438 ),
439 (
440 text("third"),
441 Value::Map(make_map(&[("pos", Value::U32(3))])),
442 ),
443 ];
444 let indexed = Value::map_ref_into_indexed_string_map::<u32>(&map, "pos").unwrap();
445 let keys: Vec<_> = indexed.keys().collect();
446 assert_eq!(keys, vec!["first", "second", "third"]);
447 }
448
449 #[test]
450 fn map_ref_into_indexed_string_map_error_missing_sort_key() {
451 let map: ValueMap = vec![(
452 text("item"),
453 Value::Map(make_map(&[("other", Value::U32(1))])),
454 )];
455 let result = Value::map_ref_into_indexed_string_map::<u32>(&map, "pos");
456 assert!(result.is_err());
457 }
458
459 #[test]
464 fn get_key_found() {
465 let map = make_map(&[("x", Value::U32(42))]);
466 let val = map.get_key("x").unwrap();
467 assert_eq!(*val, Value::U32(42));
468 }
469
470 #[test]
471 fn get_key_not_found_errors() {
472 let map = make_map(&[("x", Value::U32(42))]);
473 assert!(map.get_key("y").is_err());
474 }
475
476 #[test]
477 fn get_optional_key_none_for_missing() {
478 let map = make_map(&[("x", Value::U32(42))]);
479 assert_eq!(map.get_optional_key("y"), None);
480 }
481
482 #[test]
483 fn get_optional_key_ignores_non_text_keys() {
484 let map: ValueMap = vec![(Value::U32(1), Value::U32(2))];
485 assert_eq!(map.get_optional_key("1"), None);
486 }
487
488 #[test]
493 fn remove_key_success() {
494 let mut map = make_map(&[("a", Value::U32(1)), ("b", Value::U32(2))]);
495 let removed = map.remove_key("a").unwrap();
496 assert_eq!(removed, Value::U32(1));
497 assert_eq!(map.len(), 1);
498 }
499
500 #[test]
501 fn remove_key_not_found_errors() {
502 let mut map = make_map(&[("a", Value::U32(1))]);
503 assert!(map.remove_key("missing").is_err());
504 }
505
506 #[test]
507 fn remove_optional_key_returns_none_for_missing() {
508 let mut map = make_map(&[("a", Value::U32(1))]);
509 assert_eq!(map.remove_optional_key("missing"), None);
510 }
511
512 #[test]
513 fn remove_optional_key_returns_value() {
514 let mut map = make_map(&[("a", Value::U32(1))]);
515 assert_eq!(map.remove_optional_key("a"), Some(Value::U32(1)));
516 assert!(map.is_empty());
517 }
518
519 #[test]
524 fn remove_optional_key_value_by_value_key() {
525 let mut map: ValueMap = vec![
526 (Value::U32(10), Value::Bool(true)),
527 (text("x"), Value::Bool(false)),
528 ];
529 let removed = map.remove_optional_key_value(&Value::U32(10));
530 assert_eq!(removed, Some(Value::Bool(true)));
531 assert_eq!(map.len(), 1);
532 }
533
534 #[test]
535 fn remove_optional_key_value_not_found() {
536 let mut map = make_map(&[("a", Value::U32(1))]);
537 assert_eq!(map.remove_optional_key_value(&Value::U32(99)), None);
538 }
539
540 #[test]
545 fn insert_string_key_value_appends() {
546 let mut map: ValueMap = vec![];
547 map.insert_string_key_value("hello".to_string(), Value::Bool(true));
548 assert_eq!(map.len(), 1);
549 assert_eq!(map.get_optional_key("hello"), Some(&Value::Bool(true)));
550 }
551
552 #[test]
557 fn from_btree_map_preserves_entries() {
558 let mut btree = BTreeMap::new();
559 btree.insert("b".to_string(), Value::U32(2));
560 btree.insert("a".to_string(), Value::U32(1));
561 let map = ValueMap::from_btree_map(btree);
562 assert_eq!(map.len(), 2);
563 assert_eq!(map.get_optional_key("a"), Some(&Value::U32(1)));
564 assert_eq!(map.get_optional_key("b"), Some(&Value::U32(2)));
565 }
566
567 #[test]
572 fn get_key_by_value_mut_or_insert_inserts_new() {
573 let mut map: ValueMap = vec![];
574 let val = map.get_key_by_value_mut_or_insert(&Value::U32(42), Value::Bool(true));
575 assert_eq!(*val, Value::Bool(true));
576 assert_eq!(map.len(), 1);
577 }
578
579 #[test]
580 fn get_key_by_value_mut_or_insert_returns_existing() {
581 let mut map: ValueMap = vec![(Value::U32(42), Value::Bool(false))];
582 let val = map.get_key_by_value_mut_or_insert(&Value::U32(42), Value::Bool(true));
583 assert_eq!(*val, Value::Bool(false));
584 }
585
586 #[test]
591 fn sort_by_keys_and_inner_maps_sorts_recursively() {
592 let inner = make_map(&[("z", Value::U32(1)), ("a", Value::U32(2))]);
593 let mut map = make_map(&[("b", Value::Map(inner)), ("a", Value::U32(3))]);
594 map.sort_by_keys_and_inner_maps();
595 assert_eq!(map[0].0, text("a"));
597 assert_eq!(map[1].0, text("b"));
598 if let Value::Map(ref inner) = map[1].1 {
600 assert_eq!(inner[0].0, text("a"));
601 assert_eq!(inner[1].0, text("z"));
602 } else {
603 panic!("expected inner map");
604 }
605 }
606
607 #[test]
612 fn to_btree_ref_string_map_valid() {
613 let val = Value::Map(make_map(&[("x", Value::U32(10))]));
614 let btree = val.to_btree_ref_string_map().unwrap();
615 assert_eq!(btree.get("x"), Some(&&Value::U32(10)));
616 }
617
618 #[test]
619 fn to_btree_ref_string_map_error_on_non_map() {
620 let val = Value::U32(1);
621 assert!(val.to_btree_ref_string_map().is_err());
622 }
623
624 #[test]
625 fn to_btree_ref_string_map_error_on_non_string_key() {
626 let val = Value::Map(vec![(Value::U32(1), Value::U32(2))]);
627 assert!(val.to_btree_ref_string_map().is_err());
628 }
629}
630
631impl Value {
632 pub fn into_btree_string_map(self) -> Result<BTreeMap<String, Value>, Error> {
650 Self::map_into_btree_string_map(self.into_map()?)
651 }
652
653 pub fn to_btree_ref_string_map(&self) -> Result<BTreeMap<String, &Value>, Error> {
671 Self::map_ref_into_btree_string_map(self.to_map_ref()?)
672 }
673
674 pub fn to_ref_string_map<'a, I: FromIterator<(String, &'a Value)>>(
694 &'a self,
695 ) -> Result<I, Error> {
696 Self::map_ref_into_string_map(self.to_map_ref()?)
697 }
698
699 pub fn to_ref_string_map_mut<'a, I: FromIterator<(String, &'a mut Value)>>(
719 &'a mut self,
720 ) -> Result<I, Error> {
721 Self::map_mut_ref_into_string_map(self.as_map_mut_ref()?)
722 }
723
724 pub fn map_into_btree_string_map(map: ValueMap) -> Result<BTreeMap<String, Value>, Error> {
728 map.into_iter()
729 .map(|(key, value)| {
730 let key = key
731 .into_text()
732 .map_err(|_| Error::StructureError("expected key to be string".to_string()))?;
733 Ok((key, value))
734 })
735 .collect::<Result<BTreeMap<String, Value>, Error>>()
736 }
737
738 pub fn map_ref_into_btree_string_map(
742 map: &ValueMap,
743 ) -> Result<BTreeMap<String, &Value>, Error> {
744 map.iter()
745 .map(|(key, value)| {
746 let key = key
747 .to_text()
748 .map_err(|_| Error::StructureError("expected key to be string".to_string()))?;
749 Ok((key, value))
750 })
751 .collect::<Result<BTreeMap<String, &Value>, Error>>()
752 }
753
754 pub fn map_ref_into_indexed_string_map<'a, T>(
761 map: &'a ValueMap,
762 sort_key: &str,
763 ) -> Result<IndexMap<String, &'a Value>, Error>
764 where
765 T: TryFrom<i128>
766 + TryFrom<u128>
767 + TryFrom<u64>
768 + TryFrom<i64>
769 + TryFrom<u32>
770 + TryFrom<i32>
771 + TryFrom<u16>
772 + TryFrom<i16>
773 + TryFrom<u8>
774 + TryFrom<i8>
775 + Ord,
776 {
777 for (_, value) in map.iter() {
779 value.get_integer::<T>(sort_key)?;
780 }
781
782 let mut sorted_map: Vec<_> = map.iter().collect();
783
784 sorted_map.sort_by(|(_, value_1), (_, value_2)| {
785 let pos_1: T = value_1.get_integer(sort_key).expect("expected sort key");
786 let pos_2: T = value_2.get_integer(sort_key).expect("expected sort key");
787 pos_1.cmp(&pos_2)
788 });
789
790 sorted_map
791 .into_iter()
792 .map(|(key, value)| {
793 let key = key
794 .to_text()
795 .map_err(|_| Error::StructureError("expected key to be string".to_string()))?;
796 Ok((key, value))
797 })
798 .collect::<Result<IndexMap<String, &Value>, Error>>()
799 }
800
801 pub fn map_ref_into_string_map<'a, I: FromIterator<(String, &'a Value)>>(
805 map: &'a ValueMap,
806 ) -> Result<I, Error> {
807 map.iter()
808 .map(|(key, value)| {
809 let key = key
810 .to_text()
811 .map_err(|_| Error::StructureError("expected key to be string".to_string()))?;
812 Ok((key, value))
813 })
814 .collect::<Result<I, Error>>()
815 }
816
817 pub fn map_mut_ref_into_string_map<'a, I: FromIterator<(String, &'a mut Value)>>(
821 map: &'a mut ValueMap,
822 ) -> Result<I, Error> {
823 map.iter_mut()
824 .map(|(key, value)| {
825 let key = key
826 .to_text()
827 .map_err(|_| Error::StructureError("expected key to be string".to_string()))?;
828 Ok((key, value))
829 })
830 .collect::<Result<I, Error>>()
831 }
832}