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