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