datex_core/values/core_values/
tuple.rs1use super::super::core_value_trait::CoreValueTrait;
2use crate::values::core_value::CoreValue;
3use crate::values::core_values::integer::typed_integer::TypedInteger;
4use crate::values::traits::structural_eq::StructuralEq;
5use crate::values::value::Value;
6use crate::values::value_container::ValueContainer;
7use indexmap::IndexMap;
8use indexmap::map::{IntoIter, Iter};
9use std::collections::HashMap;
10use std::fmt::{self, Display};
11use std::hash::{Hash, Hasher};
12
13#[derive(Clone, Debug, Default, Eq, PartialEq)]
14pub struct Tuple {
15 pub entries: IndexMap<ValueContainer, ValueContainer>,
16 next_int_key: u32,
17}
18impl Tuple {
19 pub fn default() -> Self {
20 Tuple {
21 entries: IndexMap::new(),
22 next_int_key: 0,
23 }
24 }
25 pub fn new(entries: IndexMap<ValueContainer, ValueContainer>) -> Self {
26 Tuple {
27 entries,
28 ..Tuple::default()
29 }
30 }
31
32 pub fn size(&self) -> usize {
33 self.entries.len()
34 }
35
36 pub(crate) fn next_int_key(&self) -> u32 {
38 self.next_int_key
39 }
40
41 pub fn get(&self, key: &ValueContainer) -> Option<&ValueContainer> {
42 self.entries.get(key)
43 }
44
45 pub fn at(&self, index: usize) -> Option<(&ValueContainer, &ValueContainer)> {
46 self.entries.get_index(index)
47 }
48
49 pub(crate) fn set<K: Into<ValueContainer>, V: Into<ValueContainer>>(
52 &mut self,
53 key: K,
54 value: V,
55 ) {
56 let key = key.into();
57 if let ValueContainer::Value(Value {
59 inner: CoreValue::Integer(typed_int),
60 ..
61 }) = key
62 && let Some(int) = typed_int.0.as_i128()
63 && int == self.next_int_key as i128
64 {
65 self.next_int_key += 1;
66 }
67 self.entries.insert(key, value.into());
68 }
69 pub fn insert<V: Into<ValueContainer>>(&mut self, value: V) {
70 self.entries
71 .insert(self.next_int_key().into(), value.into());
72 self.next_int_key += 1;
73 }
74}
75
76impl StructuralEq for Tuple {
77 fn structural_eq(&self, other: &Self) -> bool {
78 if self.size() != other.size() {
79 return false;
80 }
81 for ((key, value), (other_key, other_value)) in
82 self.entries.iter().zip(other.entries.iter())
83 {
84 if !key.structural_eq(other_key)
85 || !value.structural_eq(other_value)
86 {
87 return false;
88 }
89 }
90 true
91 }
92}
93
94impl Hash for Tuple {
95 fn hash<H: Hasher>(&self, state: &mut H) {
96 for (k, v) in &self.entries {
97 k.hash(state);
98 v.hash(state);
99 }
100 }
101}
102
103impl CoreValueTrait for Tuple {}
104
105impl Display for Tuple {
106 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
107 write!(f, "(")?;
108 for (i, (key, value)) in self.entries.iter().enumerate() {
109 if i > 0 {
110 write!(f, ", ")?;
111 }
112 write!(f, "{key}: {value}")?;
113 }
114 write!(f, ")")
115 }
116}
117
118impl<K, V> From<HashMap<K, V>> for Tuple
119where
120 K: Into<ValueContainer>,
121 V: Into<ValueContainer>,
122{
123 fn from(map: HashMap<K, V>) -> Self {
124 Tuple::new(map.into_iter().map(|(k, v)| (k.into(), v.into())).collect())
125 }
126}
127
128impl<T> FromIterator<T> for Tuple
129where
130 T: Into<ValueContainer>,
131{
132 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
133 Tuple::new(
134 iter.into_iter()
135 .enumerate()
136 .map(|(i, v)| (TypedInteger::from(i as u64).into(), v.into()))
137 .collect(),
138 )
139 }
140}
141
142impl IntoIterator for Tuple {
143 type Item = (ValueContainer, ValueContainer);
144 type IntoIter = IntoIter<ValueContainer, ValueContainer>;
145
146 fn into_iter(self) -> Self::IntoIter {
147 self.entries.into_iter()
148 }
149}
150
151impl<'a> IntoIterator for &'a Tuple {
152 type Item = (&'a ValueContainer, &'a ValueContainer);
153 type IntoIter = Iter<'a, ValueContainer, ValueContainer>;
154
155 fn into_iter(self) -> Self::IntoIter {
156 self.entries.iter()
157 }
158}
159impl From<Vec<(ValueContainer, ValueContainer)>> for Tuple {
160 fn from(vec: Vec<(ValueContainer, ValueContainer)>) -> Self {
161 Tuple::new(vec.into_iter().collect())
162 }
163}
164
165impl From<IndexMap<ValueContainer, ValueContainer>> for Tuple {
166 fn from(map: IndexMap<ValueContainer, ValueContainer>) -> Self {
167 Tuple::new(map)
168 }
169}
170impl From<IndexMap<String, ValueContainer>> for Tuple {
171 fn from(map: IndexMap<String, ValueContainer>) -> Self {
172 Tuple::new(
173 map.into_iter()
174 .map(|(k, v)| (k.into(), v))
175 .collect::<IndexMap<ValueContainer, ValueContainer>>(),
176 )
177 }
178}
179impl TryFrom<CoreValue> for Tuple {
180 type Error = String;
181
182 fn try_from(value: CoreValue) -> Result<Self, Self::Error> {
183 if let CoreValue::Tuple(tuple) = value {
184 Ok(tuple)
185 } else {
186 Err(format!("Expected CoreValue::Tuple, found {value:?}"))
187 }
188 }
189}