1use super::row::{RowSerializationContext, SerializeRow};
8use super::{RowWriter, SerializationError};
9
10pub trait BatchValues {
15 type BatchValuesIter<'r>: BatchValuesIterator<'r>
21 where
22 Self: 'r;
23
24 fn batch_values_iter(&self) -> Self::BatchValuesIter<'_>;
26}
27
28pub trait BatchValuesIterator<'bv> {
34 fn serialize_next(
36 &mut self,
37 ctx: &RowSerializationContext<'_>,
38 writer: &mut RowWriter,
39 ) -> Option<Result<(), SerializationError>>;
40
41 fn is_empty_next(&mut self) -> Option<bool>;
43
44 fn skip_next(&mut self) -> Option<()>;
46
47 #[inline]
49 fn count(mut self) -> usize
50 where
51 Self: Sized,
52 {
53 let mut count = 0;
54 while self.skip_next().is_some() {
55 count += 1;
56 }
57 count
58 }
59}
60
61pub struct BatchValuesIteratorFromIterator<IT: Iterator> {
66 it: IT,
67}
68
69impl<'bv, 'sr: 'bv, IT, SR> BatchValuesIterator<'bv> for BatchValuesIteratorFromIterator<IT>
70where
71 IT: Iterator<Item = &'sr SR>,
72 SR: SerializeRow + 'sr,
73{
74 #[inline]
75 fn serialize_next(
76 &mut self,
77 ctx: &RowSerializationContext<'_>,
78 writer: &mut RowWriter,
79 ) -> Option<Result<(), SerializationError>> {
80 self.it.next().map(|sr| sr.serialize(ctx, writer))
81 }
82
83 #[inline]
84 fn is_empty_next(&mut self) -> Option<bool> {
85 self.it.next().map(|sr| sr.is_empty())
86 }
87
88 #[inline]
89 fn skip_next(&mut self) -> Option<()> {
90 self.it.next().map(|_| ())
91 }
92
93 #[inline]
94 fn count(self) -> usize
95 where
96 Self: Sized,
97 {
98 self.it.count()
99 }
100}
101
102impl<IT> From<IT> for BatchValuesIteratorFromIterator<IT>
103where
104 IT: Iterator,
105 IT::Item: SerializeRow,
106{
107 #[inline]
108 fn from(it: IT) -> Self {
109 BatchValuesIteratorFromIterator { it }
110 }
111}
112
113pub struct BatchValuesFromIterator<'sr, IT> {
128 it: IT,
129
130 _phantom: std::marker::PhantomData<&'sr ()>,
134}
135
136impl<'sr, IT, SR> BatchValuesFromIterator<'sr, IT>
137where
138 IT: Iterator<Item = &'sr SR> + Clone,
139 SR: SerializeRow + 'sr,
140{
141 #[inline]
143 pub fn new(into_iter: impl IntoIterator<IntoIter = IT>) -> Self {
144 Self {
145 it: into_iter.into_iter(),
146 _phantom: std::marker::PhantomData,
147 }
148 }
149}
150
151impl<'sr, IT, SR> From<IT> for BatchValuesFromIterator<'sr, IT>
152where
153 IT: Iterator<Item = &'sr SR> + Clone,
154 SR: SerializeRow + 'sr,
155{
156 #[inline]
157 fn from(it: IT) -> Self {
158 Self::new(it)
159 }
160}
161
162impl<'sr, IT, SR> BatchValues for BatchValuesFromIterator<'sr, IT>
163where
164 IT: Iterator<Item = &'sr SR> + Clone,
165 SR: SerializeRow + 'sr,
166{
167 type BatchValuesIter<'r>
168 = BatchValuesIteratorFromIterator<IT>
169 where
170 Self: 'r;
171
172 #[inline]
173 fn batch_values_iter(&self) -> Self::BatchValuesIter<'_> {
174 self.it.clone().into()
175 }
176}
177
178impl<T: SerializeRow> BatchValues for [T] {
180 type BatchValuesIter<'r>
181 = BatchValuesIteratorFromIterator<std::slice::Iter<'r, T>>
182 where
183 Self: 'r;
184
185 #[inline]
186 fn batch_values_iter(&self) -> Self::BatchValuesIter<'_> {
187 self.iter().into()
188 }
189}
190
191impl<T: SerializeRow> BatchValues for Vec<T> {
193 type BatchValuesIter<'r>
194 = BatchValuesIteratorFromIterator<std::slice::Iter<'r, T>>
195 where
196 Self: 'r;
197
198 #[inline]
199 fn batch_values_iter(&self) -> Self::BatchValuesIter<'_> {
200 BatchValues::batch_values_iter(self.as_slice())
201 }
202}
203
204impl<T0: SerializeRow> BatchValues for (T0,) {
207 type BatchValuesIter<'r>
208 = BatchValuesIteratorFromIterator<std::iter::Once<&'r T0>>
209 where
210 Self: 'r;
211
212 #[inline]
213 fn batch_values_iter(&self) -> Self::BatchValuesIter<'_> {
214 std::iter::once(&self.0).into()
215 }
216}
217
218pub struct TupleValuesIter<'sr, T> {
220 tuple: &'sr T,
221 idx: usize,
222}
223
224macro_rules! impl_batch_values_for_tuple {
225 ( $($Ti:ident),* ; $($FieldI:tt),* ; $TupleSize:tt) => {
226 impl<$($Ti),+> BatchValues for ($($Ti,)+)
227 where
228 $($Ti: SerializeRow),+
229 {
230 type BatchValuesIter<'r> = TupleValuesIter<'r, ($($Ti,)+)> where Self: 'r;
231
232 #[inline]
233 fn batch_values_iter(&self) -> Self::BatchValuesIter<'_> {
234 TupleValuesIter {
235 tuple: self,
236 idx: 0,
237 }
238 }
239 }
240
241 impl<'bv, $($Ti),+> BatchValuesIterator<'bv> for TupleValuesIter<'bv, ($($Ti,)+)>
242 where
243 $($Ti: SerializeRow),+
244 {
245 #[inline]
246 fn serialize_next(
247 &mut self,
248 ctx: &RowSerializationContext<'_>,
249 writer: &mut RowWriter,
250 ) -> Option<Result<(), SerializationError>> {
251 let ret = match self.idx {
252 $(
253 $FieldI => self.tuple.$FieldI.serialize(ctx, writer),
254 )*
255 _ => return None,
256 };
257 self.idx += 1;
258 Some(ret)
259 }
260
261 #[inline]
262 fn is_empty_next(&mut self) -> Option<bool> {
263 let ret = match self.idx {
264 $(
265 $FieldI => self.tuple.$FieldI.is_empty(),
266 )*
267 _ => return None,
268 };
269 self.idx += 1;
270 Some(ret)
271 }
272
273 #[inline]
274 fn skip_next(&mut self) -> Option<()> {
275 if self.idx < $TupleSize {
276 self.idx += 1;
277 Some(())
278 } else {
279 None
280 }
281 }
282
283 #[inline]
284 fn count(self) -> usize {
285 $TupleSize - self.idx
286 }
287 }
288 }
289}
290
291impl_batch_values_for_tuple!(T0, T1; 0, 1; 2);
292impl_batch_values_for_tuple!(T0, T1, T2; 0, 1, 2; 3);
293impl_batch_values_for_tuple!(T0, T1, T2, T3; 0, 1, 2, 3; 4);
294impl_batch_values_for_tuple!(T0, T1, T2, T3, T4; 0, 1, 2, 3, 4; 5);
295impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5; 0, 1, 2, 3, 4, 5; 6);
296impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6; 0, 1, 2, 3, 4, 5, 6; 7);
297impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7; 0, 1, 2, 3, 4, 5, 6, 7; 8);
298impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8; 0, 1, 2, 3, 4, 5, 6, 7, 8; 9);
299impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9;
300 0, 1, 2, 3, 4, 5, 6, 7, 8, 9; 10);
301impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10;
302 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10; 11);
303impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11;
304 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11; 12);
305impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12;
306 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12; 13);
307impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13;
308 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13; 14);
309impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14;
310 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14; 15);
311impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15;
312 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15; 16);
313
314impl<T: BatchValues + ?Sized> BatchValues for &T {
316 type BatchValuesIter<'r>
317 = <T as BatchValues>::BatchValuesIter<'r>
318 where
319 Self: 'r;
320
321 #[inline]
322 fn batch_values_iter(&self) -> Self::BatchValuesIter<'_> {
323 <T as BatchValues>::batch_values_iter(*self)
324 }
325}
326
327#[cfg(test)]
328#[path = "batch_tests.rs"]
329pub(crate) mod tests;