1use bytes::Bytes;
7
8use crate::frame::response::result::{
9 ColumnSpec, DeserializedMetadataAndRawRows, ResultMetadata, ResultMetadataHolder,
10};
11
12use super::row::{mk_deser_err, BuiltinDeserializationErrorKind, ColumnIterator, DeserializeRow};
13use super::{DeserializationError, FrameSlice, TypeCheckError};
14use std::marker::PhantomData;
15
16#[derive(Debug)]
18pub struct RawRowIterator<'frame, 'metadata> {
19 specs: &'metadata [ColumnSpec<'metadata>],
20 remaining: usize,
21 slice: FrameSlice<'frame>,
22}
23
24impl<'frame, 'metadata> RawRowIterator<'frame, 'metadata> {
25 #[inline]
31 pub fn new(
32 remaining: usize,
33 specs: &'metadata [ColumnSpec<'metadata>],
34 slice: FrameSlice<'frame>,
35 ) -> Self {
36 Self {
37 specs,
38 remaining,
39 slice,
40 }
41 }
42
43 #[inline]
45 pub fn specs(&self) -> &'metadata [ColumnSpec<'metadata>] {
46 self.specs
47 }
48
49 #[inline]
52 pub fn rows_remaining(&self) -> usize {
53 self.remaining
54 }
55}
56
57impl<'frame, 'metadata> Iterator for RawRowIterator<'frame, 'metadata> {
58 type Item = Result<ColumnIterator<'frame, 'metadata>, DeserializationError>;
59
60 #[inline]
61 fn next(&mut self) -> Option<Self::Item> {
62 self.remaining = self.remaining.checked_sub(1)?;
63
64 let iter = ColumnIterator::new(self.specs, self.slice);
65
66 for (column_index, spec) in self.specs.iter().enumerate() {
68 if let Err(err) = self.slice.read_cql_bytes() {
69 return Some(Err(mk_deser_err::<Self>(
70 BuiltinDeserializationErrorKind::RawColumnDeserializationFailed {
71 column_index,
72 column_name: spec.name().to_owned(),
73 err: DeserializationError::new(err),
74 },
75 )));
76 }
77 }
78
79 Some(Ok(iter))
80 }
81
82 #[inline]
83 fn size_hint(&self) -> (usize, Option<usize>) {
84 (self.remaining, Some(self.remaining))
88 }
89}
90
91#[derive(Debug)]
94pub struct TypedRowIterator<'frame, 'metadata, R> {
95 inner: RawRowIterator<'frame, 'metadata>,
96 _phantom: PhantomData<R>,
97}
98
99impl<'frame, 'metadata, R> TypedRowIterator<'frame, 'metadata, R>
100where
101 R: DeserializeRow<'frame, 'metadata>,
102{
103 #[inline]
107 pub fn new(raw: RawRowIterator<'frame, 'metadata>) -> Result<Self, TypeCheckError> {
108 R::type_check(raw.specs())?;
109 Ok(Self {
110 inner: raw,
111 _phantom: PhantomData,
112 })
113 }
114
115 #[inline]
117 pub fn specs(&self) -> &'metadata [ColumnSpec<'metadata>] {
118 self.inner.specs()
119 }
120
121 #[inline]
124 pub fn rows_remaining(&self) -> usize {
125 self.inner.rows_remaining()
126 }
127}
128
129impl<'frame, 'metadata, R> Iterator for TypedRowIterator<'frame, 'metadata, R>
130where
131 R: DeserializeRow<'frame, 'metadata>,
132{
133 type Item = Result<R, DeserializationError>;
134
135 #[inline]
136 fn next(&mut self) -> Option<Self::Item> {
137 self.inner
138 .next()
139 .map(|raw| raw.and_then(|raw| R::deserialize(raw)))
140 }
141
142 #[inline]
143 fn size_hint(&self) -> (usize, Option<usize>) {
144 self.inner.size_hint()
145 }
146}
147
148#[derive(Debug)]
157pub struct RawRowLendingIterator {
158 metadata: ResultMetadataHolder,
159 remaining: usize,
160 at: usize,
161 raw_rows: Bytes,
162}
163
164impl RawRowLendingIterator {
165 #[inline]
167 pub fn new(raw_rows: DeserializedMetadataAndRawRows) -> Self {
168 let (metadata, rows_count, raw_rows) = raw_rows.into_inner();
169 Self {
170 metadata,
171 remaining: rows_count,
172 at: 0,
173 raw_rows,
174 }
175 }
176
177 #[inline]
183 #[expect(clippy::should_implement_trait)] pub fn next(&mut self) -> Option<Result<ColumnIterator, DeserializationError>> {
185 self.remaining = self.remaining.checked_sub(1)?;
186
187 let mut remaining_frame = FrameSlice::new(&self.raw_rows);
189 *remaining_frame.as_slice_mut() = &remaining_frame.as_slice()[self.at..];
191 let iter = ColumnIterator::new(self.metadata.inner().col_specs(), remaining_frame);
195
196 for (column_index, spec) in self.metadata.inner().col_specs().iter().enumerate() {
198 let remaining_frame_len_before_column_read = remaining_frame.as_slice().len();
199 if let Err(err) = remaining_frame.read_cql_bytes() {
200 return Some(Err(mk_deser_err::<Self>(
201 BuiltinDeserializationErrorKind::RawColumnDeserializationFailed {
202 column_index,
203 column_name: spec.name().to_owned(),
204 err: DeserializationError::new(err),
205 },
206 )));
207 } else {
208 let remaining_frame_len_after_column_read = remaining_frame.as_slice().len();
209 self.at +=
210 remaining_frame_len_before_column_read - remaining_frame_len_after_column_read;
211 }
212 }
213
214 Some(Ok(iter))
215 }
216
217 #[inline]
221 pub fn size_hint(&self) -> (usize, Option<usize>) {
222 (self.remaining, Some(self.remaining))
226 }
227
228 #[inline]
231 pub fn metadata(&self) -> &ResultMetadata<'_> {
232 self.metadata.inner()
233 }
234
235 #[inline]
238 pub fn rows_remaining(&self) -> usize {
239 self.remaining
240 }
241}
242
243#[cfg(test)]
244mod tests {
245
246 use bytes::Bytes;
247 use std::ops::Deref;
248 use std::sync::LazyLock;
249
250 use crate::frame::response::result::{
251 ColumnSpec, ColumnType, DeserializedMetadataAndRawRows, NativeType, ResultMetadata,
252 };
253
254 use super::super::tests::{serialize_cells, spec, CELL1, CELL2};
255 use super::{
256 ColumnIterator, DeserializationError, FrameSlice, RawRowIterator, RawRowLendingIterator,
257 TypedRowIterator,
258 };
259
260 trait LendingIterator {
261 type Item<'borrow>
262 where
263 Self: 'borrow;
264 fn lend_next(&mut self) -> Option<Result<Self::Item<'_>, DeserializationError>>;
265 }
266
267 impl<'frame, 'metadata> LendingIterator for RawRowIterator<'frame, 'metadata> {
268 type Item<'borrow>
269 = ColumnIterator<'borrow, 'borrow>
270 where
271 Self: 'borrow;
272
273 fn lend_next(&mut self) -> Option<Result<ColumnIterator<'_, '_>, DeserializationError>> {
274 self.next()
275 }
276 }
277
278 impl LendingIterator for RawRowLendingIterator {
279 type Item<'borrow> = ColumnIterator<'borrow, 'borrow>;
280
281 fn lend_next(&mut self) -> Option<Result<ColumnIterator<'_, '_>, DeserializationError>> {
282 self.next()
283 }
284 }
285
286 #[test]
287 fn test_row_iterators_basic_parse() {
288 static SPECS: &[ColumnSpec<'static>] = &[
298 spec("b1", ColumnType::Native(NativeType::Blob)),
299 spec("b2", ColumnType::Native(NativeType::Blob)),
300 ];
301 static RAW_DATA: LazyLock<Bytes> =
302 LazyLock::new(|| serialize_cells([Some(CELL1), Some(CELL2), Some(CELL2), Some(CELL1)]));
303 let raw_data = RAW_DATA.deref();
304 let specs = SPECS;
305
306 let row_iter = RawRowIterator::new(2, specs, FrameSlice::new(raw_data));
307 let lending_row_iter =
308 RawRowLendingIterator::new(DeserializedMetadataAndRawRows::new_for_test(
309 ResultMetadata::new_for_test(specs.len(), specs.to_vec()),
310 2,
311 raw_data.clone(),
312 ));
313 check(row_iter);
314 check(lending_row_iter);
315
316 fn check<I>(mut iter: I)
317 where
318 I: for<'item> LendingIterator<Item<'item> = ColumnIterator<'item, 'item>>,
319 {
320 let mut row1 = iter.lend_next().unwrap().unwrap();
321 let c11 = row1.next().unwrap().unwrap();
322 assert_eq!(c11.slice.unwrap().as_slice(), CELL1);
323 let c12 = row1.next().unwrap().unwrap();
324 assert_eq!(c12.slice.unwrap().as_slice(), CELL2);
325 assert!(row1.next().is_none());
326
327 let mut row2 = iter.lend_next().unwrap().unwrap();
328 let c21 = row2.next().unwrap().unwrap();
329 assert_eq!(c21.slice.unwrap().as_slice(), CELL2);
330 let c22 = row2.next().unwrap().unwrap();
331 assert_eq!(c22.slice.unwrap().as_slice(), CELL1);
332 assert!(row2.next().is_none());
333
334 assert!(iter.lend_next().is_none());
335 }
336 }
337
338 #[test]
339 fn test_row_iterators_too_few_rows() {
340 static SPECS: &[ColumnSpec<'static>] = &[
341 spec("b1", ColumnType::Native(NativeType::Blob)),
342 spec("b2", ColumnType::Native(NativeType::Blob)),
343 ];
344 static RAW_DATA: LazyLock<Bytes> =
345 LazyLock::new(|| serialize_cells([Some(CELL1), Some(CELL2)]));
346
347 let raw_data = RAW_DATA.deref();
348 let specs = SPECS;
349
350 let row_iter = RawRowIterator::new(2, specs, FrameSlice::new(raw_data));
351 let lending_row_iter =
352 RawRowLendingIterator::new(DeserializedMetadataAndRawRows::new_for_test(
353 ResultMetadata::new_for_test(specs.len(), specs.to_vec()),
354 2,
355 raw_data.clone(),
356 ));
357 check(row_iter);
358 check(lending_row_iter);
359
360 fn check<I>(mut iter: I)
361 where
362 I: for<'item> LendingIterator<Item<'item> = ColumnIterator<'item, 'item>>,
363 {
364 iter.lend_next().unwrap().unwrap();
365 iter.lend_next().unwrap().unwrap_err();
366 }
367 }
368
369 #[test]
370 fn test_typed_row_iterator_basic_parse() {
371 let raw_data = serialize_cells([Some(CELL1), Some(CELL2), Some(CELL2), Some(CELL1)]);
372 let specs = [
373 spec("b1", ColumnType::Native(NativeType::Blob)),
374 spec("b2", ColumnType::Native(NativeType::Blob)),
375 ];
376 let iter = RawRowIterator::new(2, &specs, FrameSlice::new(&raw_data));
377 let mut iter = TypedRowIterator::<'_, '_, (&[u8], Vec<u8>)>::new(iter).unwrap();
378
379 let (c11, c12) = iter.next().unwrap().unwrap();
380 assert_eq!(c11, CELL1);
381 assert_eq!(c12, CELL2);
382
383 let (c21, c22) = iter.next().unwrap().unwrap();
384 assert_eq!(c21, CELL2);
385 assert_eq!(c22, CELL1);
386
387 assert!(iter.next().is_none());
388 }
389
390 #[test]
391 fn test_typed_row_iterator_wrong_type() {
392 let raw_data = Bytes::new();
393 let specs = [
394 spec("b1", ColumnType::Native(NativeType::Blob)),
395 spec("b2", ColumnType::Native(NativeType::Blob)),
396 ];
397 let iter = RawRowIterator::new(0, &specs, FrameSlice::new(&raw_data));
398 assert!(TypedRowIterator::<'_, '_, (i32, i64)>::new(iter).is_err());
399 }
400}