1use crate::{
2 collections::HashMap,
3 prelude::*,
4 random::RandomState,
5 shared_values::shared_container::KeyNotFoundError,
6 traits::structural_eq::StructuralEq,
7 values::{
8 core_value::CoreValue,
9 value::Value,
10 value_container::{ValueContainer, ValueKey},
11 },
12};
13
14use core::{
15 fmt::{self, Display},
16 hash::{Hash, Hasher},
17 result::Result,
18};
19use indexmap::IndexMap;
20
21#[derive(Clone, Debug, Eq, PartialEq)]
22pub enum Map {
23 Dynamic(IndexMap<ValueContainer, ValueContainer, RandomState>),
25 Structural(Vec<(ValueContainer, ValueContainer)>),
27 StructuralWithStringKeys(Vec<(String, ValueContainer)>), }
30
31#[derive(Debug, Clone, PartialEq)]
32pub enum MapAccessError {
33 KeyNotFound(KeyNotFoundError),
34 Immutable,
35}
36
37impl Display for MapAccessError {
38 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
39 match self {
40 MapAccessError::KeyNotFound(err) => {
41 core::write!(f, "{}", err)
42 }
43 MapAccessError::Immutable => {
44 core::write!(f, "Map is immutable")
45 }
46 }
47 }
48}
49
50impl Default for Map {
51 fn default() -> Self {
52 Map::Dynamic(IndexMap::default())
53 }
54}
55
56impl Map {
57 pub fn new(
58 entries: IndexMap<ValueContainer, ValueContainer, RandomState>,
59 ) -> Self {
60 Map::Dynamic(entries)
61 }
62
63 pub fn is_structural(&self) -> bool {
64 core::matches!(
65 self,
66 Map::StructuralWithStringKeys(_) | Map::Structural(_)
67 )
68 }
69
70 pub fn size(&self) -> usize {
71 match self {
72 Map::Dynamic(map) => map.len(),
73 Map::Structural(vec) => vec.len(),
74 Map::StructuralWithStringKeys(vec) => vec.len(),
75 }
76 }
77
78 pub fn is_empty(&self) -> bool {
79 self.size() == 0
80 }
81
82 pub fn get<'a>(
85 &self,
86 key: impl Into<ValueKey<'a>>,
87 ) -> Result<&ValueContainer, KeyNotFoundError> {
88 let key = key.into();
89 match self {
90 Map::Dynamic(map) => key.with_value_container(|key| map.get(key)),
91 Map::Structural(vec) => key.with_value_container(|key| {
92 vec.iter().find(|(k, _)| k == key).map(|(_, v)| v)
93 }),
94 Map::StructuralWithStringKeys(vec) => {
95 if let Some(string) = key.try_as_text() {
97 vec.iter().find(|(k, _)| k == string).map(|(_, v)| v)
98 } else {
99 None
100 }
101 }
102 }
103 .ok_or_else(|| KeyNotFoundError { key: key.into() })
104 }
105
106 pub fn has<'a>(&self, key: impl Into<ValueKey<'a>>) -> bool {
108 match self {
109 Map::Dynamic(map) => {
110 key.into().with_value_container(|key| map.contains_key(key))
111 }
112 Map::Structural(vec) => key
113 .into()
114 .with_value_container(|key| vec.iter().any(|(k, _)| k == key)),
115 Map::StructuralWithStringKeys(vec) => {
116 if let Some(string) = key.into().try_as_text() {
118 vec.iter().any(|(k, _)| k == string)
119 } else {
120 false
121 }
122 }
123 }
124 }
125
126 pub fn delete<'a>(
128 &mut self,
129 key: impl Into<ValueKey<'a>>,
130 ) -> Result<ValueContainer, MapAccessError> {
131 let key = key.into();
132 match self {
133 Map::Dynamic(map) => key.with_value_container(|key| {
134 map.shift_remove(key).ok_or_else(|| {
135 MapAccessError::KeyNotFound(KeyNotFoundError {
136 key: key.clone(),
137 })
138 })
139 }),
140 Map::Structural(_) | Map::StructuralWithStringKeys(_) => {
141 Err(MapAccessError::Immutable)
142 }
143 }
144 }
145
146 pub fn clear(&mut self) -> Result<(), MapAccessError> {
148 match self {
149 Map::Dynamic(map) => {
150 map.clear();
151 Ok(())
152 }
153 Map::Structural(_) | Map::StructuralWithStringKeys(_) => {
154 Err(MapAccessError::Immutable)
155 }
156 }
157 }
158
159 pub(crate) fn set<'a>(
161 &mut self,
162 key: impl Into<ValueKey<'a>>,
163 value: impl Into<ValueContainer>,
164 ) {
165 self.try_set(key, value)
166 .expect("Setting value in map failed");
167 }
168
169 pub(crate) fn try_set<'a>(
172 &mut self,
173 key: impl Into<ValueKey<'a>>,
174 value: impl Into<ValueContainer>,
175 ) -> Result<(), KeyNotFoundError> {
176 let key = key.into();
177 match self {
178 Map::Dynamic(map) => {
179 key.with_value_container(|key| {
180 map.insert(key.clone(), value.into());
181 });
182 Ok(())
183 }
184 Map::Structural(vec) => key.with_value_container(|key| {
185 if let Some((_, v)) = vec.iter_mut().find(|(k, _)| k == key) {
186 *v = value.into();
187 Ok(())
188 } else {
189 Err(KeyNotFoundError { key: key.clone() })
190 }
191 }),
192 Map::StructuralWithStringKeys(vec) => {
193 if let Some(string) = key.try_as_text() {
194 if let Some((_, v)) =
195 vec.iter_mut().find(|(k, _)| k == string)
196 {
197 *v = value.into();
198 Ok(())
199 } else {
200 Err(KeyNotFoundError { key: key.into() })
201 }
202 } else {
203 Err(KeyNotFoundError { key: key.into() })
204 }
205 }
206 }
207 }
208
209 pub(crate) fn iter(&self) -> MapIterator<'_> {
210 MapIterator {
211 map: self,
212 index: 0,
213 }
214 }
215}
216
217#[derive(Clone)]
218pub enum BorrowedMapKey<'a> {
219 Text(&'a str),
220 Value(&'a ValueContainer),
221}
222
223impl<'a> From<&'a MapKey> for BorrowedMapKey<'a> {
224 fn from(key: &'a MapKey) -> Self {
225 match key {
226 MapKey::Text(text) => BorrowedMapKey::Text(text),
227 MapKey::Value(value) => BorrowedMapKey::Value(value),
228 }
229 }
230}
231
232impl<'a> From<BorrowedMapKey<'a>> for ValueContainer {
233 fn from(key: BorrowedMapKey) -> Self {
234 match key {
235 BorrowedMapKey::Text(text) => {
236 ValueContainer::Local(Value::from(text))
237 }
238 BorrowedMapKey::Value(value) => value.clone(),
239 }
240 }
241}
242
243impl Hash for BorrowedMapKey<'_> {
244 fn hash<H: Hasher>(&self, state: &mut H) {
245 match self {
246 BorrowedMapKey::Text(text) => text.hash(state),
247 BorrowedMapKey::Value(value) => value.hash(state),
248 }
249 }
250}
251
252impl StructuralEq for BorrowedMapKey<'_> {
253 fn structural_eq(&self, other: &Self) -> bool {
254 match (self, other) {
255 (BorrowedMapKey::Text(a), BorrowedMapKey::Text(b)) => a == b,
256 (BorrowedMapKey::Value(a), BorrowedMapKey::Value(b)) => {
257 a.structural_eq(b)
258 }
259 (BorrowedMapKey::Text(a), BorrowedMapKey::Value(b))
260 | (BorrowedMapKey::Value(b), BorrowedMapKey::Text(a)) => {
261 if let ValueContainer::Local(Value {
262 inner: CoreValue::Text(text),
263 ..
264 }) = b
265 {
266 a == &text.0
267 } else {
268 false
269 }
270 }
271 }
272 }
273}
274
275impl Display for BorrowedMapKey<'_> {
276 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
277 match self {
278 BorrowedMapKey::Text(string) => core::write!(f, "\"{}\"", string),
280 BorrowedMapKey::Value(value) => core::write!(f, "{value}"),
281 }
282 }
283}
284
285#[derive(Debug)]
286pub enum MapKey {
287 Text(String),
288 Value(ValueContainer),
289}
290
291impl From<MapKey> for ValueContainer {
292 fn from(key: MapKey) -> Self {
293 match key {
294 MapKey::Text(text) => ValueContainer::Local(Value::from(text)),
295 MapKey::Value(value) => value,
296 }
297 }
298}
299
300impl<'a> From<&'a MapKey> for ValueKey<'a> {
301 fn from(key: &'a MapKey) -> Self {
302 match key {
303 MapKey::Text(text) => ValueKey::Text(Cow::Borrowed(text)),
304 MapKey::Value(value) => ValueKey::Value(Cow::Borrowed(value)),
305 }
306 }
307}
308
309impl Display for MapKey {
310 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
311 match self {
312 MapKey::Text(text) => core::write!(f, "{text}"),
313 MapKey::Value(value) => core::write!(f, "{value}"),
314 }
315 }
316}
317
318pub struct MapIterator<'a> {
319 map: &'a Map,
320 index: usize,
321}
322
323impl<'a> Iterator for MapIterator<'a> {
324 type Item = (BorrowedMapKey<'a>, &'a ValueContainer);
325
326 fn next(&mut self) -> Option<Self::Item> {
327 match self.map {
328 Map::Dynamic(map) => {
329 let item = map.iter().nth(self.index);
330 self.index += 1;
331 item.map(|(k, v)| {
332 let key = match k {
333 ValueContainer::Local(Value {
334 inner: CoreValue::Text(text),
335 ..
336 }) => BorrowedMapKey::Text(&text.0),
337 _ => BorrowedMapKey::Value(k),
338 };
339 (key, v)
340 })
341 }
342 Map::Structural(vec) => {
343 if self.index < vec.len() {
344 let item = &vec[self.index];
345 self.index += 1;
346 let key = match &item.0 {
347 ValueContainer::Local(Value {
348 inner: CoreValue::Text(text),
349 ..
350 }) => BorrowedMapKey::Text(&text.0),
351 _ => BorrowedMapKey::Value(&item.0),
352 };
353 Some((key, &item.1))
354 } else {
355 None
356 }
357 }
358 Map::StructuralWithStringKeys(vec) => {
359 if self.index < vec.len() {
360 let item = &vec[self.index];
361 self.index += 1;
362 Some((BorrowedMapKey::Text(&item.0), &item.1))
363 } else {
364 None
365 }
366 }
367 }
368 }
369}
370
371pub enum MapMutIterator<'a> {
372 Dynamic(indexmap::map::IterMut<'a, ValueContainer, ValueContainer>),
373 Fixed(core::slice::IterMut<'a, (ValueContainer, ValueContainer)>),
374 Structural(core::slice::IterMut<'a, (String, ValueContainer)>),
375}
376
377impl<'a> Iterator for MapMutIterator<'a> {
378 type Item = (BorrowedMapKey<'a>, &'a mut ValueContainer);
379
380 fn next(&mut self) -> Option<Self::Item> {
381 match self {
382 MapMutIterator::Dynamic(iter) => iter.next().map(|(k, v)| {
383 let key = match k {
384 ValueContainer::Local(Value {
385 inner: CoreValue::Text(text),
386 ..
387 }) => BorrowedMapKey::Text(&text.0),
388 _ => BorrowedMapKey::Value(k),
389 };
390 (key, v)
391 }),
392 MapMutIterator::Fixed(iter) => iter.next().map(|(k, v)| {
393 let key = match k {
394 ValueContainer::Local(Value {
395 inner: CoreValue::Text(text),
396 ..
397 }) => BorrowedMapKey::Text(&text.0),
398 _ => BorrowedMapKey::Value(k),
399 };
400 (key, v)
401 }),
402 MapMutIterator::Structural(iter) => iter
403 .next()
404 .map(|(k, v)| (BorrowedMapKey::Text(k.as_str()), v)),
405 }
406 }
407}
408
409pub struct IntoMapIterator {
410 map: Map,
411 index: usize,
412}
413
414impl Iterator for IntoMapIterator {
415 type Item = (MapKey, ValueContainer);
416
417 fn next(&mut self) -> Option<Self::Item> {
418 match &self.map {
420 Map::Dynamic(map) => {
421 let item = map.iter().nth(self.index);
422 self.index += 1;
423 item.map(|(k, v)| {
424 let key = match k {
425 ValueContainer::Local(Value {
426 inner: CoreValue::Text(text),
427 ..
428 }) => MapKey::Text(text.0.clone()),
429 _ => MapKey::Value(k.clone()),
430 };
431 (key, v.clone())
432 })
433 }
434 Map::Structural(vec) => {
435 if self.index < vec.len() {
436 let item = &vec[self.index];
437 self.index += 1;
438 let key = match &item.0 {
439 ValueContainer::Local(Value {
440 inner: CoreValue::Text(text),
441 ..
442 }) => MapKey::Text(text.0.clone()),
443 _ => MapKey::Value(item.0.clone()),
444 };
445 Some((key, item.1.clone()))
446 } else {
447 None
448 }
449 }
450 Map::StructuralWithStringKeys(vec) => {
451 if self.index < vec.len() {
452 let item = &vec[self.index];
453 self.index += 1;
454 Some((MapKey::Text(item.0.clone()), item.1.clone()))
455 } else {
456 None
457 }
458 }
459 }
460 }
461}
462
463impl StructuralEq for Map {
464 fn structural_eq(&self, other: &Self) -> bool {
465 if self.size() != other.size() {
466 return false;
467 }
468 for ((key, value), (other_key, other_value)) in
469 self.iter().zip(other.iter())
470 {
471 if !key.structural_eq(&other_key)
472 || !value.structural_eq(other_value)
473 {
474 return false;
475 }
476 }
477 true
478 }
479}
480
481impl Hash for Map {
482 fn hash<H: Hasher>(&self, state: &mut H) {
483 for (k, v) in self.iter() {
484 k.hash(state);
485 v.hash(state);
486 }
487 }
488}
489
490impl Display for Map {
491 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
492 core::write!(f, "{{")?;
493 for (i, (key, value)) in self.iter().enumerate() {
494 if i > 0 {
495 core::write!(f, ", ")?;
496 }
497 core::write!(f, "{key}: {value}")?;
498 }
499 core::write!(f, "}}")
500 }
501}
502
503impl<K, V> From<HashMap<K, V>> for Map
504where
505 K: Into<ValueContainer>,
506 V: Into<ValueContainer>,
507{
508 fn from(map: HashMap<K, V>) -> Self {
509 Map::new(map.into_iter().map(|(k, v)| (k.into(), v.into())).collect())
510 }
511}
512
513impl IntoIterator for Map {
514 type Item = (MapKey, ValueContainer);
515 type IntoIter = IntoMapIterator;
516
517 fn into_iter(self) -> Self::IntoIter {
518 IntoMapIterator {
519 map: self,
520 index: 0,
521 }
522 }
523}
524
525impl<'a> IntoIterator for &'a mut Map {
526 type Item = (BorrowedMapKey<'a>, &'a mut ValueContainer);
527 type IntoIter = MapMutIterator<'a>;
528
529 fn into_iter(self) -> Self::IntoIter {
530 match self {
531 Map::Dynamic(map) => MapMutIterator::Dynamic(map.iter_mut()),
532 Map::Structural(vec) => MapMutIterator::Fixed(vec.iter_mut()),
533 Map::StructuralWithStringKeys(vec) => {
534 MapMutIterator::Structural(vec.iter_mut())
535 }
536 }
537 }
538}
539
540impl From<Vec<(ValueContainer, ValueContainer)>> for Map {
541 fn from(vec: Vec<(ValueContainer, ValueContainer)>) -> Self {
543 Map::new(vec.into_iter().collect())
544 }
545}
546
547impl From<Vec<(String, ValueContainer)>> for Map {
548 fn from(vec: Vec<(String, ValueContainer)>) -> Self {
550 Map::new(
551 vec.into_iter()
552 .map(|(k, v)| (k.into(), v))
553 .collect::<IndexMap<ValueContainer, ValueContainer, RandomState>>(),
554 )
555 }
556}
557
558impl From<Vec<(MapKey, ValueContainer)>> for Map {
559 fn from(vec: Vec<(MapKey, ValueContainer)>) -> Self {
560 let has_only_text_keys = vec.iter().all(|(k, _)| {
561 matches!(k, MapKey::Text(_))
562 || matches!(
563 k,
564 MapKey::Value(ValueContainer::Local(Value {
565 inner: CoreValue::Text(_),
566 ..
567 }))
568 )
569 });
570 if has_only_text_keys {
571 let mut entries: Vec<(String, ValueContainer)> =
572 Vec::with_capacity(vec.len());
573 for (k, v) in vec {
574 match k {
575 MapKey::Text(text) => {
576 entries.push((text, v));
577 }
578 MapKey::Value(value) => {
579 if let ValueContainer::Local(Value {
580 inner: CoreValue::Text(text),
581 ..
582 }) = value
583 {
584 entries.push((text.0, v));
585 } else {
586 unreachable!(); }
588 }
589 }
590 }
591 Map::StructuralWithStringKeys(entries)
592 } else {
593 let mut map = Map::default();
594 for (k, v) in vec {
595 map.set(&k, v);
596 }
597 map
598 }
599 }
600}
601
602impl<K, V> FromIterator<(K, V)> for Map
603where
604 K: Into<ValueContainer>,
605 V: Into<ValueContainer>,
606{
607 fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
608 Map::Dynamic(
609 iter.into_iter()
610 .map(|(k, v)| (k.into(), v.into()))
611 .collect(),
612 )
613 }
614}
615
616impl<K, V> From<IndexMap<K, V, RandomState>> for Map
617where
618 K: Into<ValueContainer>,
619 V: Into<ValueContainer>,
620{
621 fn from(map: IndexMap<K, V, RandomState>) -> Self {
622 Map::new(
623 map.into_iter()
624 .map(|(k, v)| (k.into(), v.into()))
625 .collect::<IndexMap<ValueContainer, ValueContainer, RandomState>>(),
626 )
627 }
628}
629
630impl TryFrom<CoreValue> for Map {
631 type Error = String;
632
633 fn try_from(value: CoreValue) -> Result<Self, Self::Error> {
634 if let CoreValue::Map(map) = value {
635 Ok(map)
636 } else {
637 Err(format!("Expected CoreValue::Map, found {value:?}"))
638 }
639 }
640}
641
642#[cfg(test)]
643mod tests {
644 use crate::{
645 prelude::*,
646 shared_values::{
647 pointer::Pointer, shared_container::SharedContainer,
648 shared_value_container::SharedValueContainer,
649 },
650 values::{
651 core_values::{
652 decimal::{Decimal, typed_decimal::TypedDecimal},
653 map::Map,
654 },
655 value_container::ValueContainer,
656 },
657 };
658
659 #[test]
660 fn test_map() {
661 let mut map = Map::default();
662 map.set("key1", 42);
663 map.set("key2", "value2");
664 assert_eq!(map.size(), 2);
665 assert_eq!(map.get("key1").unwrap().to_string(), "42");
666 assert_eq!(map.get("key2").unwrap().to_string(), "\"value2\"");
667 assert_eq!(map.to_string(), r#"{"key1": 42, "key2": "value2"}"#);
668 }
669
670 #[test]
671 fn test_duplicate_keys() {
672 let mut map = Map::default();
673 map.set("key1", 42);
674 map.set("key1", "new_value");
675 assert_eq!(map.size(), 1);
676 assert_eq!(map.get("key1").unwrap().to_string(), "\"new_value\"");
677 }
678
679 #[test]
680 fn test_ref_keys() {
681 let mut map = Map::default();
682 let key = ValueContainer::Shared(SharedContainer::boxed(
683 ValueContainer::from(42),
684 Pointer::NULL,
685 ));
686 map.set(&key, "value");
687 assert_eq!(map.size(), 1);
689 assert!(map.has(&key));
690 assert_eq!(map.get(&key).unwrap().to_string(), "\"value\"");
691
692 let new_key = ValueContainer::Shared(SharedContainer::boxed(
694 ValueContainer::from(42),
695 Pointer::NULL,
696 ));
697 assert!(!map.has(&new_key));
698 assert!(map.get(&new_key).is_err());
699 }
700
701 #[test]
702 fn test_decimal_nan_value_key() {
703 let mut map = Map::default();
704 let nan_value = ValueContainer::from(Decimal::Nan);
705 map.set(&nan_value, "value");
706 assert_eq!(map.size(), 1);
708 assert!(map.has(&nan_value));
709
710 let new_nan_value = ValueContainer::from(Decimal::Nan);
712 assert!(map.has(&new_nan_value));
713
714 map.set(&new_nan_value, "new_value");
716 assert_eq!(map.size(), 1);
717 }
718
719 #[test]
720 fn test_float_nan_value_key() {
721 let mut map = Map::default();
722 let nan_value = ValueContainer::from(f64::NAN);
723 map.set(&nan_value, "value");
724 assert_eq!(map.size(), 1);
726 assert!(map.has(&nan_value));
727
728 let new_nan_value = ValueContainer::from(f64::NAN);
730 assert!(map.has(&new_nan_value));
731
732 let float32_nan_value = ValueContainer::from(f32::NAN);
734 assert!(!map.has(&float32_nan_value));
735
736 map.set(&new_nan_value, "new_value");
738 assert_eq!(map.size(), 1);
739 }
740
741 #[test]
742 fn test_decimal_zero_value_key() {
743 let mut map = Map::default();
744 let zero_value = ValueContainer::from(Decimal::Zero);
745 map.set(&zero_value, "value");
746 assert_eq!(map.size(), 1);
748 assert!(map.has(&zero_value));
749
750 let new_zero_value = ValueContainer::from(Decimal::Zero);
752 assert!(map.has(&new_zero_value));
753
754 let neg_zero_value = ValueContainer::from(Decimal::NegZero);
756 assert!(map.has(&neg_zero_value));
757
758 map.set(&neg_zero_value, "new_value");
760 assert_eq!(map.size(), 1);
761 }
762
763 #[test]
764 fn test_float_zero_value_key() {
765 let mut map = Map::default();
766 let zero_value = ValueContainer::from(0.0f64);
767 map.set(&zero_value, "value");
768 assert_eq!(map.size(), 1);
770 assert!(map.has(&zero_value));
771 let new_zero_value = ValueContainer::from(0.0f64);
773 assert!(map.has(&new_zero_value));
774 let neg_zero_value = ValueContainer::from(-0.0f64);
776 assert!(map.has(&neg_zero_value));
777
778 map.set(&neg_zero_value, "new_value");
780 assert_eq!(map.size(), 1);
781
782 let float32_zero_value = ValueContainer::from(0.0f32);
784 assert!(!map.has(&float32_zero_value));
785 }
786
787 #[test]
788 fn test_typed_big_decimal_key() {
789 let mut map = Map::default();
790 let zero_big_decimal =
791 ValueContainer::from(TypedDecimal::Decimal(Decimal::Zero));
792 map.set(&zero_big_decimal, "value");
793 assert_eq!(map.size(), 1);
795 assert!(map.has(&zero_big_decimal));
796 let new_zero_big_decimal =
798 ValueContainer::from(TypedDecimal::Decimal(Decimal::Zero));
799 assert!(map.has(&new_zero_big_decimal));
800 let neg_zero_big_decimal =
802 ValueContainer::from(TypedDecimal::Decimal(Decimal::NegZero));
803 assert!(map.has(&neg_zero_big_decimal));
804
805 map.set(&neg_zero_big_decimal, "new_value");
807 assert_eq!(map.size(), 1);
808 }
809}