partiql_value/
list.rs

1use std::cmp::Ordering;
2
3use std::fmt::{Debug, Formatter};
4use std::hash::{Hash, Hasher};
5
6use std::{slice, vec};
7
8use crate::sort::NullSortedValue;
9use crate::{Bag, EqualityValue, NullableEq, Value};
10#[cfg(feature = "serde")]
11use serde::{Deserialize, Serialize};
12
13#[derive(Default, Eq, Clone)]
14#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
15/// Represents a `PartiQL` List value, e.g. [1, 2, 'one']
16pub struct List(Vec<Value>);
17
18impl List {
19    #[inline]
20    pub fn push(&mut self, value: Value) {
21        self.0.push(value);
22    }
23
24    #[inline]
25    #[must_use]
26    pub fn len(&self) -> usize {
27        self.0.len()
28    }
29
30    #[inline]
31    #[must_use]
32    pub fn is_empty(&self) -> bool {
33        self.len() == 0
34    }
35
36    #[inline]
37    #[must_use]
38    pub fn get(&self, idx: i64) -> Option<&Value> {
39        self.0.get(idx as usize)
40    }
41
42    #[inline]
43    pub fn get_mut(&mut self, idx: i64) -> Option<&mut Value> {
44        self.0.get_mut(idx as usize)
45    }
46
47    #[inline]
48    #[must_use]
49    pub fn take_val(self, idx: i64) -> Option<Value> {
50        self.0.into_iter().nth(idx as usize)
51    }
52
53    #[inline]
54    #[must_use]
55    pub fn iter(&self) -> ListIter<'_> {
56        ListIter(self.0.iter())
57    }
58
59    #[inline]
60    pub fn reserve(&mut self, additional: usize) {
61        self.0.reserve(additional);
62    }
63
64    #[inline]
65    #[must_use]
66    pub fn to_vec(self) -> Vec<Value> {
67        self.0
68    }
69}
70
71impl Extend<Value> for List {
72    #[inline]
73    fn extend<Iter: IntoIterator<Item = Value>>(&mut self, iter: Iter) {
74        let iterator = iter.into_iter();
75        let (lower_bound, _) = iterator.size_hint();
76        self.reserve(lower_bound);
77        iterator.for_each(move |v| self.push(v));
78    }
79}
80
81impl From<Vec<Value>> for List {
82    #[inline]
83    fn from(values: Vec<Value>) -> Self {
84        List(values)
85    }
86}
87
88impl From<Bag> for List {
89    #[inline]
90    fn from(bag: Bag) -> Self {
91        List(bag.to_vec())
92    }
93}
94
95impl<T> FromIterator<T> for List
96where
97    T: Into<Value>,
98{
99    #[inline]
100    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> List {
101        let iterator = iter.into_iter().map(Into::into);
102        iterator.collect::<Vec<_>>().into()
103    }
104}
105
106#[macro_export]
107macro_rules! list {
108    () => (
109        $crate::List::from(vec![])
110    );
111    ($elem:expr; $n:expr) => (
112        $crate::List::from(vec![Value::from($elem); $n])
113    );
114    ($($x:expr),+ $(,)?) => (
115        $crate::List::from(vec![$(Value::from($x)),+])
116    );
117}
118
119impl<'a> IntoIterator for &'a List {
120    type Item = &'a Value;
121    type IntoIter = ListIter<'a>;
122
123    fn into_iter(self) -> Self::IntoIter {
124        ListIter(self.0.iter())
125    }
126}
127
128#[derive(Debug, Clone)]
129pub struct ListIter<'a>(slice::Iter<'a, Value>);
130
131impl<'a> Iterator for ListIter<'a> {
132    type Item = &'a Value;
133
134    #[inline]
135    fn next(&mut self) -> Option<Self::Item> {
136        self.0.next()
137    }
138
139    #[inline]
140    fn size_hint(&self) -> (usize, Option<usize>) {
141        self.0.size_hint()
142    }
143}
144
145impl IntoIterator for List {
146    type Item = Value;
147    type IntoIter = ListIntoIterator;
148
149    fn into_iter(self) -> ListIntoIterator {
150        ListIntoIterator(self.0.into_iter())
151    }
152}
153
154pub struct ListIntoIterator(vec::IntoIter<Value>);
155
156impl Iterator for ListIntoIterator {
157    type Item = Value;
158
159    #[inline]
160    fn next(&mut self) -> Option<Self::Item> {
161        self.0.next()
162    }
163
164    #[inline]
165    fn size_hint(&self) -> (usize, Option<usize>) {
166        self.0.size_hint()
167    }
168}
169
170impl Debug for List {
171    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
172        f.debug_list().entries(&self.0).finish()
173    }
174}
175
176impl PartialEq for List {
177    fn eq(&self, other: &Self) -> bool {
178        let wrap = EqualityValue::<true, false, _>;
179        NullableEq::eq(&wrap(self), &wrap(other)) == Value::Boolean(true)
180    }
181}
182
183impl<const NULLS_EQUAL: bool, const NAN_EQUAL: bool> NullableEq
184    for EqualityValue<'_, NULLS_EQUAL, NAN_EQUAL, List>
185{
186    #[inline(always)]
187    fn eq(&self, other: &Self) -> Value {
188        if self.0.len() != other.0.len() {
189            return Value::Boolean(false);
190        }
191        for (v1, v2) in self.0.iter().zip(other.0.iter()) {
192            let wrap = EqualityValue::<{ NULLS_EQUAL }, { NAN_EQUAL }, Value>;
193            if NullableEq::eqg(&wrap(v1), &wrap(v2)) != Value::Boolean(true) {
194                return Value::Boolean(false);
195            }
196        }
197        Value::Boolean(true)
198    }
199
200    #[inline(always)]
201    fn eqg(&self, rhs: &Self) -> Value {
202        let wrap = EqualityValue::<'_, true, { NAN_EQUAL }, _>;
203        NullableEq::eq(&wrap(self.0), &wrap(rhs.0))
204    }
205}
206
207impl PartialOrd for List {
208    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
209        Some(self.cmp(other))
210    }
211}
212
213impl<const NULLS_FIRST: bool> Ord for NullSortedValue<'_, NULLS_FIRST, List> {
214    fn cmp(&self, other: &Self) -> Ordering {
215        let wrap = NullSortedValue::<{ NULLS_FIRST }, _>;
216
217        let mut l = self.0 .0.iter();
218        let mut r = other.0 .0.iter();
219
220        loop {
221            match (l.next(), r.next()) {
222                (None, None) => return Ordering::Equal,
223                (Some(_), None) => return Ordering::Greater,
224                (None, Some(_)) => return Ordering::Less,
225                (Some(lv), Some(rv)) => match wrap(lv).cmp(&wrap(rv)) {
226                    Ordering::Less => return Ordering::Less,
227                    Ordering::Greater => return Ordering::Greater,
228                    Ordering::Equal => continue,
229                },
230            }
231        }
232    }
233}
234
235impl Ord for List {
236    fn cmp(&self, other: &Self) -> Ordering {
237        let mut l = self.0.iter();
238        let mut r = other.0.iter();
239
240        loop {
241            match (l.next(), r.next()) {
242                (None, None) => return Ordering::Equal,
243                (Some(_), None) => return Ordering::Greater,
244                (None, Some(_)) => return Ordering::Less,
245                (Some(lv), Some(rv)) => match lv.cmp(rv) {
246                    Ordering::Less => return Ordering::Less,
247                    Ordering::Greater => return Ordering::Greater,
248                    Ordering::Equal => continue,
249                },
250            }
251        }
252    }
253}
254
255impl Hash for List {
256    fn hash<H: Hasher>(&self, state: &mut H) {
257        for v in &self.0 {
258            v.hash(state);
259        }
260    }
261}