polars_arrow/bitmap/utils/
zip_validity.rs1use crate::bitmap::utils::BitmapIter;
2use crate::bitmap::Bitmap;
3use crate::trusted_len::TrustedLen;
4
5#[derive(Debug, Clone)]
7pub struct ZipValidityIter<T, I, V>
8where
9 I: Iterator<Item = T>,
10 V: Iterator<Item = bool>,
11{
12 values: I,
13 validity: V,
14}
15
16impl<T, I, V> ZipValidityIter<T, I, V>
17where
18 I: Iterator<Item = T>,
19 V: Iterator<Item = bool>,
20{
21 pub fn new(values: I, validity: V) -> Self {
25 assert_eq!(values.size_hint(), validity.size_hint());
26 Self { values, validity }
27 }
28}
29
30impl<T, I, V> Iterator for ZipValidityIter<T, I, V>
31where
32 I: Iterator<Item = T>,
33 V: Iterator<Item = bool>,
34{
35 type Item = Option<T>;
36
37 #[inline]
38 fn next(&mut self) -> Option<Self::Item> {
39 let value = self.values.next();
40 let is_valid = self.validity.next();
41 is_valid
42 .zip(value)
43 .map(|(is_valid, value)| is_valid.then(|| value))
44 }
45
46 #[inline]
47 fn size_hint(&self) -> (usize, Option<usize>) {
48 self.values.size_hint()
49 }
50
51 #[inline]
52 fn nth(&mut self, n: usize) -> Option<Self::Item> {
53 let value = self.values.nth(n);
54 let is_valid = self.validity.nth(n);
55 is_valid
56 .zip(value)
57 .map(|(is_valid, value)| is_valid.then(|| value))
58 }
59}
60
61impl<T, I, V> DoubleEndedIterator for ZipValidityIter<T, I, V>
62where
63 I: DoubleEndedIterator<Item = T>,
64 V: DoubleEndedIterator<Item = bool>,
65{
66 #[inline]
67 fn next_back(&mut self) -> Option<Self::Item> {
68 let value = self.values.next_back();
69 let is_valid = self.validity.next_back();
70 is_valid
71 .zip(value)
72 .map(|(is_valid, value)| is_valid.then(|| value))
73 }
74}
75
76unsafe impl<T, I, V> TrustedLen for ZipValidityIter<T, I, V>
77where
78 I: TrustedLen<Item = T>,
79 V: TrustedLen<Item = bool>,
80{
81}
82
83impl<T, I, V> ExactSizeIterator for ZipValidityIter<T, I, V>
84where
85 I: ExactSizeIterator<Item = T>,
86 V: ExactSizeIterator<Item = bool>,
87{
88}
89
90#[derive(Debug, Clone)]
97pub enum ZipValidity<T, I, V>
98where
99 I: Iterator<Item = T>,
100 V: Iterator<Item = bool>,
101{
102 Required(I),
104 Optional(ZipValidityIter<T, I, V>),
106}
107
108impl<T, I, V> ZipValidity<T, I, V>
109where
110 I: Iterator<Item = T>,
111 V: Iterator<Item = bool>,
112{
113 pub fn new(values: I, validity: Option<V>) -> Self {
115 match validity {
116 Some(validity) => Self::Optional(ZipValidityIter::new(values, validity)),
117 _ => Self::Required(values),
118 }
119 }
120}
121
122impl<'a, T, I> ZipValidity<T, I, BitmapIter<'a>>
123where
124 I: Iterator<Item = T>,
125{
126 pub fn new_with_validity(values: I, validity: Option<&'a Bitmap>) -> Self {
129 match validity.and_then(|validity| (validity.unset_bits() > 0).then(|| validity.iter())) {
131 Some(validity) => Self::Optional(ZipValidityIter::new(values, validity)),
132 _ => Self::Required(values),
133 }
134 }
135}
136
137impl<T, I, V> Iterator for ZipValidity<T, I, V>
138where
139 I: Iterator<Item = T>,
140 V: Iterator<Item = bool>,
141{
142 type Item = Option<T>;
143
144 #[inline]
145 fn next(&mut self) -> Option<Self::Item> {
146 match self {
147 Self::Required(values) => values.next().map(Some),
148 Self::Optional(zipped) => zipped.next(),
149 }
150 }
151
152 #[inline]
153 fn size_hint(&self) -> (usize, Option<usize>) {
154 match self {
155 Self::Required(values) => values.size_hint(),
156 Self::Optional(zipped) => zipped.size_hint(),
157 }
158 }
159
160 #[inline]
161 fn nth(&mut self, n: usize) -> Option<Self::Item> {
162 match self {
163 Self::Required(values) => values.nth(n).map(Some),
164 Self::Optional(zipped) => zipped.nth(n),
165 }
166 }
167}
168
169impl<T, I, V> DoubleEndedIterator for ZipValidity<T, I, V>
170where
171 I: DoubleEndedIterator<Item = T>,
172 V: DoubleEndedIterator<Item = bool>,
173{
174 #[inline]
175 fn next_back(&mut self) -> Option<Self::Item> {
176 match self {
177 Self::Required(values) => values.next_back().map(Some),
178 Self::Optional(zipped) => zipped.next_back(),
179 }
180 }
181}
182
183impl<T, I, V> ExactSizeIterator for ZipValidity<T, I, V>
184where
185 I: ExactSizeIterator<Item = T>,
186 V: ExactSizeIterator<Item = bool>,
187{
188}
189
190unsafe impl<T, I, V> TrustedLen for ZipValidity<T, I, V>
191where
192 I: TrustedLen<Item = T>,
193 V: TrustedLen<Item = bool>,
194{
195}
196
197impl<T, I, V> ZipValidity<T, I, V>
198where
199 I: Iterator<Item = T>,
200 V: Iterator<Item = bool>,
201{
202 pub fn unwrap_required(self) -> I {
204 match self {
205 ZipValidity::Required(i) => i,
206 _ => panic!("Could not 'unwrap_required'. 'ZipValidity' iterator has nulls."),
207 }
208 }
209
210 pub fn unwrap_optional(self) -> ZipValidityIter<T, I, V> {
212 match self {
213 ZipValidity::Optional(i) => i,
214 _ => panic!("Could not 'unwrap_optional'. 'ZipValidity' iterator has no nulls."),
215 }
216 }
217}