1use itertools::Itertools;
2
3use std::cmp::Ordering;
4
5use std::fmt::{Debug, Formatter};
6use std::hash::{Hash, Hasher};
7use std::iter::{zip, Zip};
8use std::vec;
9
10use crate::sort::NullSortedValue;
11use crate::{BindingsName, EqualityValue, NullableEq, Value};
12#[cfg(feature = "serde")]
13use serde::{Deserialize, Serialize};
14
15#[derive(Default, Eq, Clone)]
16#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
17pub struct Tuple {
18 attrs: Vec<String>,
19 vals: Vec<Value>,
20}
21
22impl Tuple {
23 #[must_use]
24 pub fn new() -> Self {
25 Tuple {
26 attrs: vec![],
27 vals: vec![],
28 }
29 }
30
31 #[inline]
32 pub fn insert(&mut self, attr: &str, val: Value) {
33 self.attrs.push(attr.to_string());
34 self.vals.push(val);
35 }
36
37 #[inline]
38 #[must_use]
39 pub fn len(&self) -> usize {
40 self.attrs.len()
41 }
42
43 #[inline]
44 #[must_use]
45 pub fn is_empty(&self) -> bool {
46 self.len() == 0
47 }
48
49 #[inline]
50 #[must_use]
56 pub fn tuple_concat(&self, other: &Tuple) -> Self {
57 other
58 .pairs()
59 .chain(self.pairs())
60 .unique_by(|(a, _)| *a)
61 .map(|(a, v)| (a, v.clone()))
62 .collect()
63 }
64
65 #[inline]
66 #[must_use]
67 pub fn get(&self, attr: &BindingsName<'_>) -> Option<&Value> {
68 self.find_value(attr).map(|i| &self.vals[i])
69 }
70
71 #[inline]
72 #[must_use]
73 pub fn take_val(self, attr: &BindingsName<'_>) -> Option<Value> {
74 self.find_value(attr)
75 .and_then(|i| self.vals.into_iter().nth(i))
76 }
77
78 #[inline(always)]
79 fn find_value(&self, attr: &BindingsName<'_>) -> Option<usize> {
80 let matcher = attr.matcher();
81 self.attrs.iter().position(|a| matcher.matches(a))
82 }
83
84 #[inline]
85 pub fn remove(&mut self, attr: &BindingsName<'_>) -> Option<Value> {
86 match self.find_value(attr) {
87 Some(i) => {
88 self.attrs.remove(i);
89 Some(self.vals.remove(i))
90 }
91 _ => None,
92 }
93 }
94
95 #[inline]
96 #[must_use]
97 pub fn pairs(&self) -> PairsIter<'_> {
98 PairsIter(zip(self.attrs.iter(), self.vals.iter()))
99 }
100
101 #[inline]
102 #[must_use]
103 pub fn into_pairs(self) -> PairsIntoIter {
104 PairsIntoIter(zip(self.attrs, self.vals))
105 }
106
107 #[inline]
108 pub fn values(&self) -> impl Iterator<Item = &Value> + Clone {
109 self.vals.iter()
110 }
111
112 #[inline]
113 pub fn into_values(self) -> impl Iterator<Item = Value> {
114 self.vals.into_iter()
115 }
116}
117
118#[derive(Debug, Clone)]
119pub struct PairsIter<'a>(Zip<std::slice::Iter<'a, String>, std::slice::Iter<'a, Value>>);
120
121impl<'a> Iterator for PairsIter<'a> {
122 type Item = (&'a String, &'a Value);
123
124 #[inline]
125 fn next(&mut self) -> Option<Self::Item> {
126 self.0.next()
127 }
128
129 #[inline]
130 fn size_hint(&self) -> (usize, Option<usize>) {
131 self.0.size_hint()
132 }
133}
134
135#[derive(Debug, Clone)]
136pub struct PairsIntoIter(Zip<std::vec::IntoIter<String>, std::vec::IntoIter<Value>>);
137
138impl Iterator for PairsIntoIter {
139 type Item = (String, Value);
140
141 #[inline]
142 fn next(&mut self) -> Option<Self::Item> {
143 self.0.next()
144 }
145
146 #[inline]
147 fn size_hint(&self) -> (usize, Option<usize>) {
148 self.0.size_hint()
149 }
150}
151
152impl<const N: usize, T> From<[(&str, T); N]> for Tuple
153where
154 T: Into<Value>,
155{
156 #[inline]
157 fn from(arr: [(&str, T); N]) -> Self {
158 arr.into_iter()
159 .fold(Tuple::new(), |mut acc: Tuple, (attr, val)| {
160 acc.insert(attr, val.into());
161 acc
162 })
163 }
164}
165
166impl<S, T> FromIterator<(S, T)> for Tuple
167where
168 S: Into<String>,
169 T: Into<Value>,
170{
171 #[inline]
172 fn from_iter<I: IntoIterator<Item = (S, T)>>(iter: I) -> Tuple {
173 let iterator = iter.into_iter();
174 let (lower, _) = iterator.size_hint();
175 let mut attrs = Vec::with_capacity(lower);
176 let mut vals = Vec::with_capacity(lower);
177 for (k, v) in iterator {
178 attrs.push(k.into());
179 vals.push(v.into());
180 }
181 Tuple { attrs, vals }
182 }
183}
184
185impl<S, T> Extend<(S, T)> for Tuple
186where
187 S: AsRef<str>,
188 T: Into<Value>,
189{
190 fn extend<I: IntoIterator<Item = (S, T)>>(&mut self, iter: I) {
191 for (k, v) in iter {
192 self.insert(k.as_ref(), v.into());
193 }
194 }
195}
196
197impl Iterator for Tuple {
198 type Item = (String, Value);
199
200 #[inline]
201 fn next(&mut self) -> Option<Self::Item> {
202 match (self.attrs.pop(), self.vals.pop()) {
203 (Some(attr), Some(val)) => Some((attr, val)),
204 _ => None,
205 }
206 }
207
208 #[inline]
209 fn size_hint(&self) -> (usize, Option<usize>) {
210 (self.attrs.len(), Some(self.attrs.len()))
211 }
212}
213
214impl PartialEq for Tuple {
215 fn eq(&self, other: &Self) -> bool {
216 let wrap = EqualityValue::<true, false, _>;
217 NullableEq::eq(&wrap(self), &wrap(other)) == Value::Boolean(true)
218 }
219}
220
221impl<const NULLS_EQUAL: bool, const NAN_EQUAL: bool> NullableEq
222 for EqualityValue<'_, NULLS_EQUAL, NAN_EQUAL, Tuple>
223{
224 #[inline(always)]
225 fn eq(&self, other: &Self) -> Value {
226 if self.0.vals.len() != other.0.vals.len() {
227 return Value::Boolean(false);
228 }
229 for ((ls, lv), (rs, rv)) in self.0.pairs().sorted().zip(other.0.pairs().sorted()) {
230 if ls != rs {
231 return Value::Boolean(false);
232 }
233 let wrap = EqualityValue::<{ NULLS_EQUAL }, { NAN_EQUAL }, Value>;
234 if NullableEq::eqg(&wrap(lv), &wrap(rv)) != Value::Boolean(true) {
235 return Value::Boolean(false);
236 }
237 }
238 Value::Boolean(true)
239 }
240
241 #[inline(always)]
242 fn eqg(&self, rhs: &Self) -> Value {
243 let wrap = EqualityValue::<'_, true, { NAN_EQUAL }, _>;
244 NullableEq::eq(&wrap(self.0), &wrap(rhs.0))
245 }
246}
247
248impl PartialOrd for Tuple {
249 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
250 Some(self.cmp(other))
251 }
252}
253
254impl Hash for Tuple {
255 fn hash<H: Hasher>(&self, state: &mut H) {
256 for (k, v) in self.pairs().sorted() {
257 k.hash(state);
258 v.hash(state);
259 }
260 }
261}
262
263impl Debug for Tuple {
264 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
265 write!(f, "{{")?;
266 let mut iter = self.pairs().peekable();
267 while let Some((k, v)) = iter.next() {
268 if iter.peek().is_some() {
269 write!(f, " '{k}': {v:?},")?;
270 } else {
271 write!(f, " '{k}': {v:?} ")?;
272 }
273 }
274 write!(f, "}}")
275 }
276}
277
278impl<const NULLS_FIRST: bool> Ord for NullSortedValue<'_, NULLS_FIRST, Tuple> {
279 fn cmp(&self, other: &Self) -> Ordering {
280 let wrap = NullSortedValue::<{ NULLS_FIRST }, Value>;
281
282 let self_pairs = self.0.pairs();
283 let other_pairs = other.0.pairs();
284 let mut p1 = self_pairs.sorted();
285 let mut p2 = other_pairs.sorted();
286
287 loop {
288 return match (p1.next(), p2.next()) {
289 (None, None) => Ordering::Equal,
290 (Some(_), None) => Ordering::Greater,
291 (None, Some(_)) => Ordering::Less,
292 (Some((ls, lv)), Some((rs, rv))) => match (ls.cmp(rs), wrap(lv).cmp(&wrap(rv))) {
293 (Ordering::Less, _) => Ordering::Less,
294 (Ordering::Greater, _) => Ordering::Greater,
295 (_, Ordering::Less) => Ordering::Less,
296 (_, Ordering::Greater) => Ordering::Greater,
297 (_, Ordering::Equal) => continue,
298 },
299 };
300 }
301 }
302}
303
304impl Ord for Tuple {
305 fn cmp(&self, other: &Self) -> Ordering {
306 let self_pairs = self.pairs();
307 let other_pairs = other.pairs();
308 let mut p1 = self_pairs.sorted();
309 let mut p2 = other_pairs.sorted();
310
311 loop {
312 return match (p1.next(), p2.next()) {
313 (None, None) => Ordering::Equal,
314 (Some(_), None) => Ordering::Greater,
315 (None, Some(_)) => Ordering::Less,
316 (Some(lv), Some(rv)) => match lv.cmp(&rv) {
317 Ordering::Less => Ordering::Less,
318 Ordering::Greater => Ordering::Greater,
319 Ordering::Equal => continue,
320 },
321 };
322 }
323 }
324}
325
326#[macro_export]
327macro_rules! tuple {
328 () => (
329 $crate::Tuple::new()
330 );
331 ($(($x:expr, $y:expr)),+ $(,)?) => (
332 $crate::Tuple::from([$(($x, Value::from($y))),+])
333 );
334}