Skip to main content

hara_native/lang/data/
map_entry.rs

1use crate::core::Value;
2use crate::lang::hash::JavaHash;
3use crate::lang::protocol::{
4    HashType, ICount, IDisplay, IEquality, IHash, IMetadata, INth, IObjType, IPair, ObjType,
5};
6use std::rc::Rc;
7
8/// The immutable runtime representation of a map entry.
9///
10/// Compact tuples deliberately remain a separate internal representation for
11/// small vectors. A `MapEntry` is the only value that implements `IPair`.
12#[derive(Debug, Clone)]
13pub struct MapEntry {
14    key: Value,
15    value: Value,
16    metadata: Option<Rc<crate::lang::data::Metadata>>,
17}
18
19impl MapEntry {
20    pub fn new(key: Value, value: Value) -> Self {
21        Self {
22            key,
23            value,
24            metadata: None,
25        }
26    }
27
28    pub fn key(&self) -> &Value {
29        &self.key
30    }
31
32    pub fn value(&self) -> &Value {
33        &self.value
34    }
35
36    pub fn nth(&self, index: usize) -> Option<&Value> {
37        match index {
38            0 => Some(&self.key),
39            1 => Some(&self.value),
40            _ => None,
41        }
42    }
43
44    pub fn iter(&self) -> std::array::IntoIter<&Value, 2> {
45        [&self.key, &self.value].into_iter()
46    }
47}
48
49impl PartialEq for MapEntry {
50    fn eq(&self, other: &Self) -> bool {
51        self.key == other.key && self.value == other.value
52    }
53}
54
55impl Eq for MapEntry {}
56
57impl ICount for MapEntry {
58    fn count(&self) -> usize {
59        2
60    }
61}
62
63impl INth<Value> for MapEntry {
64    fn nth(&self, index: usize) -> Option<&Value> {
65        self.nth(index)
66    }
67}
68
69impl IPair<Value, Value> for MapEntry {
70    fn key(&self) -> &Value {
71        self.key()
72    }
73
74    fn value(&self) -> &Value {
75        self.value()
76    }
77}
78
79impl IMetadata for MapEntry {
80    type Metadata = Rc<crate::lang::data::Metadata>;
81
82    fn meta(&self) -> Option<&Self::Metadata> {
83        self.metadata.as_ref()
84    }
85
86    fn with_meta(&self, metadata: Option<Self::Metadata>) -> Self {
87        Self {
88            key: self.key.clone(),
89            value: self.value.clone(),
90            metadata,
91        }
92    }
93}
94
95impl IEquality for MapEntry {
96    fn equality(&self, other: &Self) -> bool {
97        self == other
98    }
99}
100
101impl IDisplay for MapEntry {
102    fn display(&self) -> String {
103        format!("[{} {}]", self.key.display(), self.value.display())
104    }
105}
106
107impl IHash for MapEntry {
108    fn hash_calc(&self, hash_type: HashType) -> u64 {
109        crate::lang::hash::compose_ordered(
110            "SEQUENTIAL",
111            self.iter().map(|value| value.java_hash(hash_type)),
112        ) as u64
113    }
114}
115
116impl IObjType for MapEntry {
117    fn obj_type(&self) -> ObjType {
118        ObjType::MapEntry
119    }
120
121    fn hash_seed(&self) -> String {
122        "::SEQUENTIAL".into()
123    }
124}