Skip to main content

scylla_cql_core/deserialize/
value.rs

1//! Provides types for dealing with CQL value deserialization.
2
3use std::{
4    borrow::Cow,
5    collections::{BTreeMap, BTreeSet, HashMap, HashSet},
6    hash::{BuildHasher, Hash},
7    net::IpAddr,
8    sync::Arc,
9};
10
11use bytes::Bytes;
12use uuid::Uuid;
13
14use std::fmt::Display;
15
16use thiserror::Error;
17
18use super::{DeserializationError, FrameSlice, TypeCheckError, make_error_replace_rust_name};
19use crate::frame::frame_errors::LowLevelDeserializationError;
20use crate::frame::response::result::CollectionType;
21use crate::frame::response::result::UserDefinedType;
22use crate::frame::response::result::{ColumnType, NativeType};
23use crate::frame::types;
24use crate::value::CqlVarintBorrowed;
25use crate::value::{
26    Counter, CqlDate, CqlDecimal, CqlDecimalBorrowed, CqlDuration, CqlTime, CqlTimestamp,
27    CqlTimeuuid, CqlValue, CqlVarint,
28};
29
30// Re-export for backwards compatibility. These types were moved to crate::value module.
31// Note: deprecated doesn't work on re-exports, users won't get the warning.
32// Added it anyway for documentation purposes.
33// TODO(2.0): Remove those re-exports.
34#[deprecated(since = "1.5.0", note = "Moved to `scylla_cql::value` module")]
35pub use crate::value::Emptiable;
36#[deprecated(since = "1.5.0", note = "Moved to `scylla_cql::value` module")]
37pub use crate::value::MaybeEmpty;
38
39/// A type that can be deserialized from a column value inside a row that was
40/// returned from a query.
41///
42/// For tips on how to write a custom implementation of this trait, see the
43/// documentation of the parent module.
44///
45/// The crate also provides a derive macro which allows to automatically
46/// implement the trait for a custom type. For more details on what the macro
47/// is capable of, see its documentation.
48pub trait DeserializeValue<'frame, 'metadata>
49where
50    Self: Sized,
51{
52    /// Checks that the column type matches what this type expects.
53    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError>;
54
55    /// Deserialize a column value from given serialized representation.
56    ///
57    /// This function can assume that the driver called `type_check` to verify
58    /// the column's type. Note that `deserialize` is not an unsafe function,
59    /// so it should not use the assumption about `type_check` being called
60    /// as an excuse to run `unsafe` code.
61    fn deserialize(
62        typ: &'metadata ColumnType<'metadata>,
63        v: Option<FrameSlice<'frame>>,
64    ) -> Result<Self, DeserializationError>;
65}
66
67impl<'frame, 'metadata> DeserializeValue<'frame, 'metadata> for CqlValue {
68    fn type_check(_typ: &ColumnType) -> Result<(), TypeCheckError> {
69        // CqlValue accepts all possible CQL types
70        Ok(())
71    }
72
73    fn deserialize(
74        typ: &'metadata ColumnType<'metadata>,
75        v: Option<FrameSlice<'frame>>,
76    ) -> Result<Self, DeserializationError> {
77        use crate::frame::response::result::ColumnType::*;
78        use crate::frame::response::result::NativeType::*;
79
80        let mut frame_slice = ensure_not_null_frame_slice::<Self>(typ, v)?;
81
82        if frame_slice.as_slice().is_empty() {
83            match typ {
84                Native(Ascii) | Native(Blob) | Native(Text) => {
85                    // can't be empty
86                }
87                _ => return Ok(CqlValue::Empty),
88            }
89        }
90
91        // We re-create `v` from our frame_slice for delegating to other DeserializeValue impls.
92        let v = Some(frame_slice);
93
94        Ok(
95            #[deny(clippy::wildcard_enum_match_arm)]
96            match typ {
97                Native(Ascii) => {
98                    let s = String::deserialize(typ, v)?;
99                    CqlValue::Ascii(s)
100                }
101                Native(Boolean) => {
102                    let b = bool::deserialize(typ, v)?;
103                    CqlValue::Boolean(b)
104                }
105                Native(Blob) => {
106                    let b = Vec::<u8>::deserialize(typ, v)?;
107                    CqlValue::Blob(b)
108                }
109                Native(Date) => {
110                    let d = CqlDate::deserialize(typ, v)?;
111                    CqlValue::Date(d)
112                }
113                Native(Counter) => {
114                    let c = crate::value::Counter::deserialize(typ, v)?;
115                    CqlValue::Counter(c)
116                }
117                Native(Decimal) => {
118                    let d = CqlDecimal::deserialize(typ, v)?;
119                    CqlValue::Decimal(d)
120                }
121                Native(Double) => {
122                    let d = f64::deserialize(typ, v)?;
123                    CqlValue::Double(d)
124                }
125                Native(Float) => {
126                    let f = f32::deserialize(typ, v)?;
127                    CqlValue::Float(f)
128                }
129                Native(Int) => {
130                    let i = i32::deserialize(typ, v)?;
131                    CqlValue::Int(i)
132                }
133                Native(SmallInt) => {
134                    let si = i16::deserialize(typ, v)?;
135                    CqlValue::SmallInt(si)
136                }
137                Native(TinyInt) => {
138                    let ti = i8::deserialize(typ, v)?;
139                    CqlValue::TinyInt(ti)
140                }
141                Native(BigInt) => {
142                    let bi = i64::deserialize(typ, v)?;
143                    CqlValue::BigInt(bi)
144                }
145                Native(Text) => {
146                    let s = String::deserialize(typ, v)?;
147                    CqlValue::Text(s)
148                }
149                Native(Timestamp) => {
150                    let t = CqlTimestamp::deserialize(typ, v)?;
151                    CqlValue::Timestamp(t)
152                }
153                Native(Time) => {
154                    let t = CqlTime::deserialize(typ, v)?;
155                    CqlValue::Time(t)
156                }
157                Native(Timeuuid) => {
158                    let t = CqlTimeuuid::deserialize(typ, v)?;
159                    CqlValue::Timeuuid(t)
160                }
161                Native(Duration) => {
162                    let d = CqlDuration::deserialize(typ, v)?;
163                    CqlValue::Duration(d)
164                }
165                Native(Inet) => {
166                    let i = IpAddr::deserialize(typ, v)?;
167                    CqlValue::Inet(i)
168                }
169                Native(Uuid) => {
170                    let uuid = uuid::Uuid::deserialize(typ, v)?;
171                    CqlValue::Uuid(uuid)
172                }
173                Native(Varint) => {
174                    let vi = CqlVarint::deserialize(typ, v)?;
175                    CqlValue::Varint(vi)
176                }
177                Collection {
178                    typ: CollectionType::List(_type_name),
179                    ..
180                } => {
181                    let l = Vec::<CqlValue>::deserialize(typ, v)?;
182                    CqlValue::List(l)
183                }
184                Collection {
185                    typ: CollectionType::Map(_key_type, _value_type),
186                    ..
187                } => {
188                    let iter = MapIterator::<'_, '_, CqlValue, CqlValue>::deserialize(typ, v)?;
189                    let m: Vec<(CqlValue, CqlValue)> = iter.collect::<Result<_, _>>()?;
190                    CqlValue::Map(m)
191                }
192                Collection {
193                    typ: CollectionType::Set(_type_name),
194                    ..
195                } => {
196                    let s = Vec::<CqlValue>::deserialize(typ, v)?;
197                    CqlValue::Set(s)
198                }
199                Vector { .. } => {
200                    let iter = VectorIterator::deserialize(typ, v)?;
201                    let v: Vec<CqlValue> = iter.collect::<Result<_, _>>()?;
202                    CqlValue::Vector(v)
203                }
204                UserDefinedType {
205                    definition: udt, ..
206                } => {
207                    let iter = UdtIterator::deserialize(typ, v)?;
208                    let fields: Vec<(String, Option<CqlValue>)> = iter
209                        .map(|((col_name, col_type), res)| {
210                            res.and_then(|v| {
211                                let val = Option::<CqlValue>::deserialize(col_type, v.flatten())?;
212                                Ok((col_name.clone().into_owned(), val))
213                            })
214                        })
215                        .collect::<Result<_, _>>()?;
216
217                    CqlValue::UserDefinedType {
218                        keyspace: udt.keyspace.clone().into_owned(),
219                        name: udt.name.clone().into_owned(),
220                        fields,
221                    }
222                }
223                Tuple(type_names) => {
224                    let t = type_names
225                        .iter()
226                        .map(|typ| -> Result<_, DeserializationError> {
227                            let raw = if frame_slice.is_empty() {
228                                // Special case: if there are no bytes left to read, consider the tuple element as null.
229                                // This is needed to handle tuples with fewer elements than expected
230                                // (see https://github.com/scylladb/scylla-rust-driver/issues/1452 for context).
231                                None
232                            } else {
233                                frame_slice.read_cql_bytes().map_err(|e| {
234                                    mk_deser_err::<CqlValue>(
235                                        typ,
236                                        BuiltinDeserializationErrorKind::RawCqlBytesReadError(e),
237                                    )
238                                })?
239                            };
240                            raw.map(|v| CqlValue::deserialize(typ, Some(v))).transpose()
241                        })
242                        .collect::<Result<_, _>>()?;
243                    CqlValue::Tuple(t)
244                }
245            },
246        )
247    }
248}
249
250// Option represents nullability of CQL values:
251// None corresponds to null,
252// Some(val) to non-null values.
253impl<'frame, 'metadata, T> DeserializeValue<'frame, 'metadata> for Option<T>
254where
255    T: DeserializeValue<'frame, 'metadata>,
256{
257    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
258        T::type_check(typ).map_err(typck_error_replace_rust_name::<Self>)
259    }
260
261    fn deserialize(
262        typ: &'metadata ColumnType<'metadata>,
263        v: Option<FrameSlice<'frame>>,
264    ) -> Result<Self, DeserializationError> {
265        v.map(|_| T::deserialize(typ, v))
266            .transpose()
267            .map_err(deser_error_replace_rust_name::<Self>)
268    }
269}
270
271impl<'frame, 'metadata, T> DeserializeValue<'frame, 'metadata> for MaybeEmpty<T>
272where
273    T: DeserializeValue<'frame, 'metadata> + Emptiable,
274{
275    #[inline]
276    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
277        <T as DeserializeValue<'frame, 'metadata>>::type_check(typ)
278            .map_err(typck_error_replace_rust_name::<Self>)
279    }
280
281    fn deserialize(
282        typ: &'metadata ColumnType<'metadata>,
283        v: Option<FrameSlice<'frame>>,
284    ) -> Result<Self, DeserializationError> {
285        let val = ensure_not_null_slice::<Self>(typ, v)?;
286        if val.is_empty() {
287            Ok(MaybeEmpty::Empty)
288        } else {
289            let v = <T as DeserializeValue<'frame, 'metadata>>::deserialize(typ, v)
290                .map_err(deser_error_replace_rust_name::<Self>)?;
291            Ok(MaybeEmpty::Value(v))
292        }
293    }
294}
295
296macro_rules! impl_strict_type {
297    ($t:ty, [$($cql:ident)|+], $conv:expr $(, $l:lifetime)?) => {
298        impl<$($l,)? 'frame, 'metadata> DeserializeValue<'frame, 'metadata> for $t
299        where
300            $('frame: $l)?
301        {
302            fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
303                // TODO: Format the CQL type names in the same notation
304                // that ScyllaDB/Cassandra uses internally and include them
305                // in such form in the error message
306                exact_type_check!(typ, $($cql),*);
307                Ok(())
308            }
309
310            fn deserialize(
311                typ: &'metadata ColumnType<'metadata>,
312                v: Option<FrameSlice<'frame>>,
313            ) -> Result<Self, DeserializationError> {
314                $conv(typ, v)
315            }
316        }
317    };
318
319    // Convenience pattern for omitting brackets if type-checking as single types.
320    ($t:ty, $cql:ident, $conv:expr $(, $l:lifetime)?) => {
321        impl_strict_type!($t, [$cql], $conv $(, $l)*);
322    };
323}
324
325// fixed numeric types
326
327macro_rules! impl_fixed_numeric_type {
328    ($t:ty, [$($cql:ident)|+]) => {
329        impl_strict_type!(
330            $t,
331            [$($cql)|*],
332            |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
333                const SIZE: usize = std::mem::size_of::<$t>();
334                let val = ensure_not_null_slice::<Self>(typ, v)?;
335                let arr = ensure_exact_length::<Self, SIZE>(typ, val)?;
336                Ok(<$t>::from_be_bytes(*arr))
337            }
338        );
339    };
340
341    // Convenience pattern for omitting brackets if type-checking as single types.
342    ($t:ty, $cql:ident) => {
343        impl_fixed_numeric_type!($t, [$cql]);
344    };
345}
346
347impl_strict_type!(
348    bool,
349    Boolean,
350    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
351        let val = ensure_not_null_slice::<Self>(typ, v)?;
352        let arr = ensure_exact_length::<Self, 1>(typ, val)?;
353        Ok(arr[0] != 0x00)
354    }
355);
356
357impl_fixed_numeric_type!(i8, TinyInt);
358impl_fixed_numeric_type!(i16, SmallInt);
359impl_fixed_numeric_type!(i32, Int);
360impl_fixed_numeric_type!(i64, BigInt);
361impl_fixed_numeric_type!(f32, Float);
362impl_fixed_numeric_type!(f64, Double);
363
364// other numeric types
365
366impl_strict_type!(
367    CqlVarint,
368    Varint,
369    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
370        let val = ensure_not_null_slice::<Self>(typ, v)?;
371        Ok(CqlVarint::from_signed_bytes_be_slice(val))
372    }
373);
374
375impl_strict_type!(
376    CqlVarintBorrowed<'b>,
377    Varint,
378    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
379        let val = ensure_not_null_slice::<Self>(typ, v)?;
380        Ok(CqlVarintBorrowed::from_signed_bytes_be_slice(val))
381    },
382    'b
383);
384
385#[cfg(feature = "num-bigint-03")]
386impl_strict_type!(
387    num_bigint_03::BigInt,
388    Varint,
389    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
390        let val = ensure_not_null_slice::<Self>(typ, v)?;
391        Ok(num_bigint_03::BigInt::from_signed_bytes_be(val))
392    }
393);
394
395#[cfg(feature = "num-bigint-04")]
396impl_strict_type!(
397    num_bigint_04::BigInt,
398    Varint,
399    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
400        let val = ensure_not_null_slice::<Self>(typ, v)?;
401        Ok(num_bigint_04::BigInt::from_signed_bytes_be(val))
402    }
403);
404
405impl_strict_type!(
406    CqlDecimal,
407    Decimal,
408    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
409        let mut val = ensure_not_null_slice::<Self>(typ, v)?;
410        let scale = types::read_int(&mut val).map_err(|err| {
411            mk_deser_err::<Self>(
412                typ,
413                BuiltinDeserializationErrorKind::BadDecimalScale(err.into()),
414            )
415        })?;
416        Ok(CqlDecimal::from_signed_be_bytes_slice_and_exponent(
417            val, scale,
418        ))
419    }
420);
421
422impl_strict_type!(
423    CqlDecimalBorrowed<'b>,
424    Decimal,
425    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
426        let mut val = ensure_not_null_slice::<Self>(typ, v)?;
427        let scale = types::read_int(&mut val).map_err(|err| {
428            mk_deser_err::<Self>(
429                typ,
430                BuiltinDeserializationErrorKind::BadDecimalScale(err.into()),
431            )
432        })?;
433        Ok(CqlDecimalBorrowed::from_signed_be_bytes_slice_and_exponent(
434            val, scale,
435        ))
436    },
437    'b
438);
439
440#[cfg(feature = "bigdecimal-04")]
441impl_strict_type!(
442    bigdecimal_04::BigDecimal,
443    Decimal,
444    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
445        let mut val = ensure_not_null_slice::<Self>(typ, v)?;
446        let scale = types::read_int(&mut val).map_err(|err| {
447            mk_deser_err::<Self>(
448                typ,
449                BuiltinDeserializationErrorKind::BadDecimalScale(err.into()),
450            )
451        })? as i64;
452        let int_value = bigdecimal_04::num_bigint::BigInt::from_signed_bytes_be(val);
453        Ok(bigdecimal_04::BigDecimal::from((int_value, scale)))
454    }
455);
456
457// blob
458
459impl_strict_type!(
460    &'a [u8],
461    Blob,
462    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
463        let val = ensure_not_null_slice::<Self>(typ, v)?;
464        Ok(val)
465    },
466    'a
467);
468impl_strict_type!(
469    Vec<u8>,
470    Blob,
471    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
472        let val = ensure_not_null_slice::<Self>(typ, v)?;
473        Ok(val.to_vec())
474    }
475);
476impl_strict_type!(
477    Bytes,
478    Blob,
479    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
480        let val = ensure_not_null_owned::<Self>(typ, v)?;
481        Ok(val)
482    }
483);
484
485// string
486
487macro_rules! impl_string_type {
488    ($t:ty, $conv:expr $(, $l:lifetime)?) => {
489        impl_strict_type!(
490            $t,
491            [Ascii | Text],
492            $conv
493            $(, $l)?
494        );
495    }
496}
497
498fn check_ascii<T>(typ: &ColumnType, s: &[u8]) -> Result<(), DeserializationError> {
499    if matches!(typ, ColumnType::Native(NativeType::Ascii)) && !s.is_ascii() {
500        return Err(mk_deser_err::<T>(
501            typ,
502            BuiltinDeserializationErrorKind::ExpectedAscii,
503        ));
504    }
505    Ok(())
506}
507
508impl_string_type!(
509    &'a str,
510    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
511        let val = ensure_not_null_slice::<Self>(typ, v)?;
512        check_ascii::<&str>(typ, val)?;
513        let s = std::str::from_utf8(val).map_err(|err| {
514            mk_deser_err::<Self>(typ, BuiltinDeserializationErrorKind::InvalidUtf8(err))
515        })?;
516        Ok(s)
517    },
518    'a
519);
520impl_string_type!(
521    String,
522    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
523        let val = ensure_not_null_slice::<Self>(typ, v)?;
524        check_ascii::<String>(typ, val)?;
525        let s = std::str::from_utf8(val).map_err(|err| {
526            mk_deser_err::<Self>(typ, BuiltinDeserializationErrorKind::InvalidUtf8(err))
527        })?;
528        Ok(s.to_string())
529    }
530);
531
532// TODO: Consider support for deserialization of string::String<Bytes>
533
534// counter
535
536impl_strict_type!(
537    Counter,
538    Counter,
539    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
540        let val = ensure_not_null_slice::<Self>(typ, v)?;
541        let arr = ensure_exact_length::<Self, 8>(typ, val)?;
542        let counter = i64::from_be_bytes(*arr);
543        Ok(Counter(counter))
544    }
545);
546
547// date and time types
548
549// duration
550impl_strict_type!(
551    CqlDuration,
552    Duration,
553    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
554        let mut val = ensure_not_null_slice::<Self>(typ, v)?;
555
556        macro_rules! mk_err {
557            ($err: expr) => {
558                mk_deser_err::<Self>(typ, $err)
559            };
560        }
561
562        let months_i64 = types::vint_decode(&mut val).map_err(|err| {
563            mk_err!(BuiltinDeserializationErrorKind::BadDate {
564                date_field: "months",
565                err: err.into()
566            })
567        })?;
568        let months = i32::try_from(months_i64)
569            .map_err(|_| mk_err!(BuiltinDeserializationErrorKind::ValueOverflow))?;
570
571        let days_i64 = types::vint_decode(&mut val).map_err(|err| {
572            mk_err!(BuiltinDeserializationErrorKind::BadDate {
573                date_field: "days",
574                err: err.into()
575            })
576        })?;
577        let days = i32::try_from(days_i64)
578            .map_err(|_| mk_err!(BuiltinDeserializationErrorKind::ValueOverflow))?;
579
580        let nanoseconds = types::vint_decode(&mut val).map_err(|err| {
581            mk_err!(BuiltinDeserializationErrorKind::BadDate {
582                date_field: "nanoseconds",
583                err: err.into()
584            })
585        })?;
586
587        Ok(CqlDuration {
588            months,
589            days,
590            nanoseconds,
591        })
592    }
593);
594
595impl_strict_type!(
596    CqlDate,
597    Date,
598    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
599        let val = ensure_not_null_slice::<Self>(typ, v)?;
600        let arr = ensure_exact_length::<Self, 4>(typ, val)?;
601        let days = u32::from_be_bytes(*arr);
602        Ok(CqlDate(days))
603    }
604);
605
606#[cfg(any(feature = "chrono-04", feature = "time-03"))]
607fn get_days_since_epoch_from_date_column<T>(
608    typ: &ColumnType,
609    v: Option<FrameSlice<'_>>,
610) -> Result<i64, DeserializationError> {
611    let val = ensure_not_null_slice::<T>(typ, v)?;
612    let arr = ensure_exact_length::<T, 4>(typ, val)?;
613    let days = u32::from_be_bytes(*arr);
614    let days_since_epoch = days as i64 - (1i64 << 31);
615    Ok(days_since_epoch)
616}
617
618#[cfg(feature = "chrono-04")]
619impl_strict_type!(chrono_04::NaiveDate, Date, |typ: &'metadata ColumnType<
620    'metadata,
621>,
622                                               v: Option<
623    FrameSlice<'frame>,
624>| {
625    let fail = || mk_deser_err::<Self>(typ, BuiltinDeserializationErrorKind::ValueOverflow);
626    let days_since_epoch =
627        chrono_04::Duration::try_days(get_days_since_epoch_from_date_column::<Self>(typ, v)?)
628            .ok_or_else(fail)?;
629    chrono_04::NaiveDate::from_ymd_opt(1970, 1, 1)
630        .unwrap()
631        .checked_add_signed(days_since_epoch)
632        .ok_or_else(fail)
633});
634
635#[cfg(feature = "time-03")]
636impl_strict_type!(
637    time_03::Date,
638    Date,
639    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
640        let days_since_epoch =
641            time_03::Duration::days(get_days_since_epoch_from_date_column::<Self>(typ, v)?);
642        time_03::Date::from_calendar_date(1970, time_03::Month::January, 1)
643            .unwrap()
644            .checked_add(days_since_epoch)
645            .ok_or_else(|| {
646                mk_deser_err::<Self>(typ, BuiltinDeserializationErrorKind::ValueOverflow)
647            })
648    }
649);
650
651fn get_nanos_from_time_column<T>(
652    typ: &ColumnType,
653    v: Option<FrameSlice<'_>>,
654) -> Result<i64, DeserializationError> {
655    let val = ensure_not_null_slice::<T>(typ, v)?;
656    let arr = ensure_exact_length::<T, 8>(typ, val)?;
657    let nanoseconds = i64::from_be_bytes(*arr);
658
659    // Valid values are in the range 0 to 86399999999999
660    if !(0..=86399999999999).contains(&nanoseconds) {
661        return Err(mk_deser_err::<T>(
662            typ,
663            BuiltinDeserializationErrorKind::ValueOverflow,
664        ));
665    }
666
667    Ok(nanoseconds)
668}
669
670impl_strict_type!(
671    CqlTime,
672    Time,
673    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
674        let nanoseconds = get_nanos_from_time_column::<Self>(typ, v)?;
675
676        Ok(CqlTime(nanoseconds))
677    }
678);
679
680#[cfg(feature = "chrono-04")]
681impl_strict_type!(chrono_04::NaiveTime, Time, |typ: &'metadata ColumnType<
682    'metadata,
683>,
684                                               v: Option<
685    FrameSlice<'frame>,
686>| {
687    let nanoseconds = get_nanos_from_time_column::<chrono_04::NaiveTime>(typ, v)?;
688
689    let naive_time: chrono_04::NaiveTime = CqlTime(nanoseconds)
690        .try_into()
691        .map_err(|_| mk_deser_err::<Self>(typ, BuiltinDeserializationErrorKind::ValueOverflow))?;
692    Ok(naive_time)
693});
694
695#[cfg(feature = "time-03")]
696impl_strict_type!(
697    time_03::Time,
698    Time,
699    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
700        let nanoseconds = get_nanos_from_time_column::<time_03::Time>(typ, v)?;
701
702        let time: time_03::Time = CqlTime(nanoseconds).try_into().map_err(|_| {
703            mk_deser_err::<Self>(typ, BuiltinDeserializationErrorKind::ValueOverflow)
704        })?;
705        Ok(time)
706    }
707);
708
709fn get_millis_from_timestamp_column<T>(
710    typ: &ColumnType,
711    v: Option<FrameSlice<'_>>,
712) -> Result<i64, DeserializationError> {
713    let val = ensure_not_null_slice::<T>(typ, v)?;
714    let arr = ensure_exact_length::<T, 8>(typ, val)?;
715    let millis = i64::from_be_bytes(*arr);
716
717    Ok(millis)
718}
719
720impl_strict_type!(
721    CqlTimestamp,
722    Timestamp,
723    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
724        let millis = get_millis_from_timestamp_column::<Self>(typ, v)?;
725        Ok(CqlTimestamp(millis))
726    }
727);
728
729#[cfg(feature = "chrono-04")]
730impl_strict_type!(
731    chrono_04::DateTime<chrono_04::Utc>,
732    Timestamp,
733    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
734        use chrono_04::TimeZone as _;
735
736        let millis = get_millis_from_timestamp_column::<Self>(typ, v)?;
737        match chrono_04::Utc.timestamp_millis_opt(millis) {
738            chrono_04::LocalResult::Single(datetime) => Ok(datetime),
739            _ => Err(mk_deser_err::<Self>(
740                typ,
741                BuiltinDeserializationErrorKind::ValueOverflow,
742            )),
743        }
744    }
745);
746
747#[cfg(feature = "time-03")]
748impl_strict_type!(
749    time_03::OffsetDateTime,
750    Timestamp,
751    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
752        let millis = get_millis_from_timestamp_column::<Self>(typ, v)?;
753        time_03::OffsetDateTime::from_unix_timestamp_nanos(millis as i128 * 1_000_000)
754            .map_err(|_| mk_deser_err::<Self>(typ, BuiltinDeserializationErrorKind::ValueOverflow))
755    }
756);
757
758// inet
759
760impl_strict_type!(
761    IpAddr,
762    Inet,
763    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
764        let val = ensure_not_null_slice::<Self>(typ, v)?;
765        if let Ok(ipv4) = <[u8; 4]>::try_from(val) {
766            Ok(IpAddr::from(ipv4))
767        } else if let Ok(ipv6) = <[u8; 16]>::try_from(val) {
768            Ok(IpAddr::from(ipv6))
769        } else {
770            Err(mk_deser_err::<Self>(
771                typ,
772                BuiltinDeserializationErrorKind::BadInetLength { got: val.len() },
773            ))
774        }
775    }
776);
777
778// uuid
779
780impl_strict_type!(
781    Uuid,
782    Uuid,
783    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
784        let val = ensure_not_null_slice::<Self>(typ, v)?;
785        let arr = ensure_exact_length::<Self, 16>(typ, val)?;
786        let i = u128::from_be_bytes(*arr);
787        Ok(uuid::Uuid::from_u128(i))
788    }
789);
790
791impl_strict_type!(
792    CqlTimeuuid,
793    Timeuuid,
794    |typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>| {
795        let val = ensure_not_null_slice::<Self>(typ, v)?;
796        let arr = ensure_exact_length::<Self, 16>(typ, val)?;
797        let i = u128::from_be_bytes(*arr);
798        Ok(CqlTimeuuid::from(uuid::Uuid::from_u128(i)))
799    }
800);
801
802// secrecy
803#[cfg(feature = "secrecy-08")]
804impl<'frame, 'metadata, T> DeserializeValue<'frame, 'metadata> for secrecy_08::Secret<T>
805where
806    T: DeserializeValue<'frame, 'metadata> + secrecy_08::Zeroize,
807{
808    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
809        <T as DeserializeValue<'frame, 'metadata>>::type_check(typ)
810            .map_err(typck_error_replace_rust_name::<Self>)
811    }
812
813    fn deserialize(
814        typ: &'metadata ColumnType<'metadata>,
815        v: Option<FrameSlice<'frame>>,
816    ) -> Result<Self, DeserializationError> {
817        <T as DeserializeValue<'frame, 'metadata>>::deserialize(typ, v)
818            .map(secrecy_08::Secret::new)
819            .map_err(deser_error_replace_rust_name::<Self>)
820    }
821}
822
823#[cfg(feature = "secrecy-10")]
824impl<'frame, 'metadata, T> DeserializeValue<'frame, 'metadata> for secrecy_10::SecretBox<T>
825where
826    T: DeserializeValue<'frame, 'metadata> + secrecy_10::zeroize::Zeroize,
827{
828    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
829        <T as DeserializeValue<'frame, 'metadata>>::type_check(typ)
830            .map_err(typck_error_replace_rust_name::<Self>)
831    }
832
833    fn deserialize(
834        typ: &'metadata ColumnType<'metadata>,
835        v: Option<FrameSlice<'frame>>,
836    ) -> Result<Self, DeserializationError> {
837        <T as DeserializeValue<'frame, 'metadata>>::deserialize(typ, v)
838            .map(|v| secrecy_10::SecretBox::new(Box::new(v)))
839            .map_err(deser_error_replace_rust_name::<Self>)
840    }
841}
842
843// Special implementation for SecretString (SecretBox<str>)
844#[cfg(feature = "secrecy-10")]
845impl<'frame, 'metadata> DeserializeValue<'frame, 'metadata> for secrecy_10::SecretString {
846    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
847        <String as DeserializeValue<'frame, 'metadata>>::type_check(typ)
848            .map_err(typck_error_replace_rust_name::<Self>)
849    }
850
851    fn deserialize(
852        typ: &'metadata ColumnType<'metadata>,
853        v: Option<FrameSlice<'frame>>,
854    ) -> Result<Self, DeserializationError> {
855        <String as DeserializeValue<'frame, 'metadata>>::deserialize(typ, v)
856            .map(secrecy_10::SecretString::from)
857            .map_err(deser_error_replace_rust_name::<Self>)
858    }
859}
860
861// Special implementation for SecretSlice (SecretBox<[S]>)
862#[cfg(feature = "secrecy-10")]
863impl<'frame, 'metadata, S> DeserializeValue<'frame, 'metadata> for secrecy_10::SecretSlice<S>
864where
865    S: DeserializeValue<'frame, 'metadata> + secrecy_10::zeroize::Zeroize,
866    [S]: secrecy_10::zeroize::Zeroize,
867{
868    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
869        <Vec<S> as DeserializeValue<'frame, 'metadata>>::type_check(typ)
870            .map_err(typck_error_replace_rust_name::<Self>)
871    }
872
873    fn deserialize(
874        typ: &'metadata ColumnType<'metadata>,
875        v: Option<FrameSlice<'frame>>,
876    ) -> Result<Self, DeserializationError> {
877        <Vec<S> as DeserializeValue<'frame, 'metadata>>::deserialize(typ, v)
878            .map(secrecy_10::SecretSlice::from)
879            .map_err(deser_error_replace_rust_name::<Self>)
880    }
881}
882
883// collections
884
885make_error_replace_rust_name!(
886    /// Replaces the Rust type name in a [`BuiltinTypeCheckError`] wrapped inside
887    /// a [`TypeCheckError`] with the name of `RustT`.
888    ///
889    /// This is used to ensure that error messages report the correct Rust type name
890    /// even when the error originates from a helper/inner type used during deserialization,
891    /// rather than the top-level type being deserialized.
892    ///
893    /// # Assumptions
894    /// - This function should **only** be called inside a proper `type_check()` implementation.
895    /// - It should be called **before** the error is cloned, as it attempts to mutably access
896    ///   the inner error stored in `Arc`; if the `Arc` has already been cloned,
897    ///   a new [`BuiltinTypeCheckError`] will be allocated with the updated name instead.
898    pub(crate),
899    typck_error_replace_rust_name,
900    TypeCheckError,
901    BuiltinTypeCheckError
902);
903
904make_error_replace_rust_name!(
905    /// Replaces the Rust type name in a [`BuiltinDeserializationError`] wrapped inside
906    /// a [`DeserializationError`] with the name of `RustT`.
907    ///
908    /// This is used to ensure that error messages report the correct Rust type name
909    /// even when the error originates from a helper/inner type used during deserialization,
910    /// rather than the top-level type being deserialized.
911    ///
912    /// # Assumptions
913    /// - This function should **only** be called inside a proper `deserialize()` implementation.
914    /// - It should be called **before** the error is cloned, as it attempts to mutably access
915    ///   the inner error stored in `Arc`; if the `Arc` has already been cloned,
916    ///   a new [`BuiltinDeserializationError`] will be allocated with the updated name instead.
917    pub,
918    deser_error_replace_rust_name,
919    DeserializationError,
920    BuiltinDeserializationError
921);
922
923// lists and sets
924
925/// An iterator over either a CQL set or list.
926#[derive(Debug, Clone)]
927pub struct ListlikeIterator<'frame, 'metadata, T> {
928    coll_typ: &'metadata ColumnType<'metadata>,
929    elem_typ: &'metadata ColumnType<'metadata>,
930    raw_iter: FixedLengthBytesSequenceIterator<'frame>,
931    phantom_data: std::marker::PhantomData<T>,
932}
933
934impl<'frame, 'metadata, T> ListlikeIterator<'frame, 'metadata, T> {
935    fn new(
936        coll_typ: &'metadata ColumnType<'metadata>,
937        elem_typ: &'metadata ColumnType<'metadata>,
938        count: usize,
939        slice: FrameSlice<'frame>,
940    ) -> Self {
941        Self {
942            coll_typ,
943            elem_typ,
944            raw_iter: FixedLengthBytesSequenceIterator::new(count, slice),
945            phantom_data: std::marker::PhantomData,
946        }
947    }
948
949    fn empty(
950        coll_typ: &'metadata ColumnType<'metadata>,
951        elem_typ: &'metadata ColumnType<'metadata>,
952    ) -> Self {
953        Self {
954            coll_typ,
955            elem_typ,
956            raw_iter: FixedLengthBytesSequenceIterator::empty(),
957            phantom_data: std::marker::PhantomData,
958        }
959    }
960}
961
962impl<'frame, 'metadata, T> DeserializeValue<'frame, 'metadata>
963    for ListlikeIterator<'frame, 'metadata, T>
964where
965    T: DeserializeValue<'frame, 'metadata>,
966{
967    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
968        match typ {
969            ColumnType::Collection {
970                frozen: _,
971                typ: CollectionType::List(el_t),
972            }
973            | ColumnType::Collection {
974                frozen: _,
975                typ: CollectionType::Set(el_t),
976            } => <T as DeserializeValue<'frame, 'metadata>>::type_check(el_t).map_err(|err| {
977                mk_typck_err::<Self>(
978                    typ,
979                    SetOrListTypeCheckErrorKind::ElementTypeCheckFailed(err),
980                )
981            }),
982            _ => Err(mk_typck_err::<Self>(
983                typ,
984                BuiltinTypeCheckErrorKind::SetOrListError(
985                    SetOrListTypeCheckErrorKind::NotSetOrList,
986                ),
987            )),
988        }
989    }
990
991    fn deserialize(
992        typ: &'metadata ColumnType<'metadata>,
993        v: Option<FrameSlice<'frame>>,
994    ) -> Result<Self, DeserializationError> {
995        let elem_typ = match typ {
996            ColumnType::Collection {
997                frozen: _,
998                typ: CollectionType::List(elem_typ),
999            }
1000            | ColumnType::Collection {
1001                frozen: _,
1002                typ: CollectionType::Set(elem_typ),
1003            } => elem_typ,
1004            _ => {
1005                unreachable!("Typecheck should have prevented this scenario!")
1006            }
1007        };
1008
1009        let mut v = if let Some(v) = v {
1010            v
1011        } else {
1012            return Ok(Self::empty(typ, elem_typ));
1013        };
1014
1015        let count = types::read_int_length(v.as_slice_mut()).map_err(|err| {
1016            mk_deser_err::<Self>(
1017                typ,
1018                SetOrListDeserializationErrorKind::LengthDeserializationFailed(
1019                    DeserializationError::new(err),
1020                ),
1021            )
1022        })?;
1023
1024        Ok(Self::new(typ, elem_typ, count, v))
1025    }
1026}
1027
1028impl<'frame, 'metadata, T> Iterator for ListlikeIterator<'frame, 'metadata, T>
1029where
1030    T: DeserializeValue<'frame, 'metadata>,
1031{
1032    type Item = Result<T, DeserializationError>;
1033
1034    fn next(&mut self) -> Option<Self::Item> {
1035        let raw = self.raw_iter.next()?.map_err(|err| {
1036            mk_deser_err::<Self>(
1037                self.coll_typ,
1038                BuiltinDeserializationErrorKind::RawCqlBytesReadError(err),
1039            )
1040        });
1041        Some(raw.and_then(|raw| {
1042            T::deserialize(self.elem_typ, raw).map_err(|err| {
1043                mk_deser_err::<Self>(
1044                    self.coll_typ,
1045                    SetOrListDeserializationErrorKind::ElementDeserializationFailed(err),
1046                )
1047            })
1048        }))
1049    }
1050
1051    // We only return `None` when underlying `FixedLengthBytesSequenceIterator` does.
1052    #[inline]
1053    fn size_hint(&self) -> (usize, Option<usize>) {
1054        self.raw_iter.size_hint()
1055    }
1056}
1057
1058// We only return `None` when underlying `FixedLengthBytesSequenceIterator` does.
1059// `FixedLengthBytesSequenceIterator` is ExactSize, so this can be too.
1060impl<'frame, 'metadata, T> ExactSizeIterator for ListlikeIterator<'frame, 'metadata, T> where
1061    T: DeserializeValue<'frame, 'metadata>
1062{
1063}
1064
1065impl<'frame, 'metadata, T> DeserializeValue<'frame, 'metadata> for Vec<T>
1066where
1067    T: DeserializeValue<'frame, 'metadata>,
1068{
1069    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
1070        // It makes sense for Set, List and Vector to deserialize to Vec.
1071        match typ {
1072            ColumnType::Collection {
1073                typ: CollectionType::List(_) | CollectionType::Set(_),
1074                ..
1075            } => ListlikeIterator::<'frame, 'metadata, T>::type_check(typ)
1076                .map_err(typck_error_replace_rust_name::<Self>),
1077            ColumnType::Vector { .. } => VectorIterator::<'frame, 'metadata, T>::type_check(typ)
1078                .map_err(typck_error_replace_rust_name::<Self>),
1079            _ => Err(mk_typck_err::<Self>(
1080                typ,
1081                BuiltinTypeCheckErrorKind::NotDeserializableToVec,
1082            )),
1083        }
1084    }
1085
1086    fn deserialize(
1087        typ: &'metadata ColumnType<'metadata>,
1088        v: Option<FrameSlice<'frame>>,
1089    ) -> Result<Self, DeserializationError> {
1090        match typ {
1091            ColumnType::Collection {
1092                typ: CollectionType::List(_) | CollectionType::Set(_),
1093                ..
1094            } => ListlikeIterator::<'frame, 'metadata, T>::deserialize(typ, v)
1095                .and_then(|it| it.collect::<Result<_, DeserializationError>>())
1096                .map_err(deser_error_replace_rust_name::<Self>),
1097            ColumnType::Vector { .. } => {
1098                VectorIterator::<'frame, 'metadata, T>::deserialize(typ, v)
1099                    .and_then(|it| it.collect::<Result<_, DeserializationError>>())
1100                    .map_err(deser_error_replace_rust_name::<Self>)
1101            }
1102            _ => unreachable!("Should be prevented by typecheck"),
1103        }
1104    }
1105}
1106
1107impl<'frame, 'metadata, T> DeserializeValue<'frame, 'metadata> for BTreeSet<T>
1108where
1109    T: DeserializeValue<'frame, 'metadata> + Ord,
1110{
1111    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
1112        // It only makes sense for Set to deserialize to BTreeSet.
1113        // Deserializing List straight to BTreeSet would be lossy.
1114        match typ {
1115            ColumnType::Collection {
1116                frozen: _,
1117                typ: CollectionType::Set(_),
1118            } => ListlikeIterator::<'frame, 'metadata, T>::type_check(typ)
1119                .map_err(typck_error_replace_rust_name::<Self>),
1120            _ => Err(mk_typck_err::<Self>(
1121                typ,
1122                SetOrListTypeCheckErrorKind::NotSet,
1123            )),
1124        }
1125    }
1126
1127    fn deserialize(
1128        typ: &'metadata ColumnType<'metadata>,
1129        v: Option<FrameSlice<'frame>>,
1130    ) -> Result<Self, DeserializationError> {
1131        ListlikeIterator::<'frame, 'metadata, T>::deserialize(typ, v)
1132            .and_then(|it| it.collect::<Result<_, DeserializationError>>())
1133            .map_err(deser_error_replace_rust_name::<Self>)
1134    }
1135}
1136
1137impl<'frame, 'metadata, T, S> DeserializeValue<'frame, 'metadata> for HashSet<T, S>
1138where
1139    T: DeserializeValue<'frame, 'metadata> + Eq + Hash,
1140    S: BuildHasher + Default + 'frame,
1141{
1142    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
1143        // It only makes sense for Set to deserialize to HashSet.
1144        // Deserializing List straight to HashSet would be lossy.
1145        match typ {
1146            ColumnType::Collection {
1147                frozen: _,
1148                typ: CollectionType::Set(_),
1149            } => ListlikeIterator::<'frame, 'metadata, T>::type_check(typ)
1150                .map_err(typck_error_replace_rust_name::<Self>),
1151            _ => Err(mk_typck_err::<Self>(
1152                typ,
1153                SetOrListTypeCheckErrorKind::NotSet,
1154            )),
1155        }
1156    }
1157
1158    fn deserialize(
1159        typ: &'metadata ColumnType<'metadata>,
1160        v: Option<FrameSlice<'frame>>,
1161    ) -> Result<Self, DeserializationError> {
1162        ListlikeIterator::<'frame, 'metadata, T>::deserialize(typ, v)
1163            .and_then(|it| it.collect::<Result<_, DeserializationError>>())
1164            .map_err(deser_error_replace_rust_name::<Self>)
1165    }
1166}
1167
1168/// A deserialization iterator over a CQL vector.
1169///
1170/// Deserialization of a vector is done in two ways, depending on the element type:
1171/// 1. If the element type is of a fixed-length, the iterator reads
1172///    a fixed, known number of bytes for each element and deserializes
1173///    according to the element type. The element count and element size
1174///    are not encoded as the count is known from the vector type
1175///    and the size is known from the element type.
1176///
1177/// 2. If the element type is of a variable-length, the iterator reads an vint
1178///    (variable-length integer) for each element, which indicates the number of bytes
1179///    to read for that element. Then, the iterator reads the specified number of bytes
1180///    and deserializes according to the element type. This, however, is in contradiction
1181///    with the CQL protocol, which specifies that the element count is encoded as a 4 byte int!
1182///    Alas, Cassandra does not respect the protocol, so ScyllaDB and this driver have to follow.
1183///
1184/// It would be nice to have a rule to determine if the element type is fixed-length or not,
1185/// however, we only have a heuristic. There are a few types that should, for all intents and purposes,
1186/// be considered fixed-length, but are not, e.g TinyInt. See ColumnType::type_size_for_vector() for the list.
1187#[derive(Debug, Clone)]
1188pub struct VectorIterator<'frame, 'metadata, T> {
1189    collection_type: &'metadata ColumnType<'metadata>,
1190    element_type: &'metadata ColumnType<'metadata>,
1191    remaining: usize,
1192    element_length: Option<usize>,
1193    slice: FrameSlice<'frame>,
1194    phantom_data: std::marker::PhantomData<T>,
1195}
1196
1197impl<'frame, 'metadata, T> VectorIterator<'frame, 'metadata, T> {
1198    fn new(
1199        collection_type: &'metadata ColumnType<'metadata>,
1200        element_type: &'metadata ColumnType<'metadata>,
1201        count: usize,
1202        element_length: Option<usize>,
1203        slice: FrameSlice<'frame>,
1204    ) -> Self {
1205        Self {
1206            collection_type,
1207            element_type,
1208            remaining: count,
1209            element_length,
1210            slice,
1211            phantom_data: std::marker::PhantomData,
1212        }
1213    }
1214}
1215
1216impl<'frame, 'metadata, T> DeserializeValue<'frame, 'metadata>
1217    for VectorIterator<'frame, 'metadata, T>
1218where
1219    T: DeserializeValue<'frame, 'metadata>,
1220{
1221    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
1222        match typ {
1223            ColumnType::Vector { typ: t, .. } => {
1224                <T as DeserializeValue<'frame, 'metadata>>::type_check(t).map_err(|err| {
1225                    mk_typck_err::<Self>(typ, VectorTypeCheckErrorKind::ElementTypeCheckFailed(err))
1226                })?;
1227                Ok(())
1228            }
1229            _ => Err(mk_typck_err::<Self>(
1230                typ,
1231                VectorTypeCheckErrorKind::NotVector,
1232            )),
1233        }
1234    }
1235
1236    fn deserialize(
1237        typ: &'metadata ColumnType<'metadata>,
1238        v: Option<FrameSlice<'frame>>,
1239    ) -> Result<Self, DeserializationError> {
1240        let (element_type, dimensions) = match typ {
1241            ColumnType::Vector {
1242                typ: element_type,
1243                dimensions,
1244            } => (element_type, dimensions),
1245            _ => {
1246                unreachable!("Typecheck should have prevented this scenario!")
1247            }
1248        };
1249
1250        let v = ensure_not_null_frame_slice::<Self>(typ, v)?;
1251
1252        Ok(Self::new(
1253            typ,
1254            element_type,
1255            *dimensions as usize,
1256            element_type.type_size_for_vector(),
1257            v,
1258        ))
1259    }
1260}
1261
1262impl<'frame, 'metadata, T> VectorIterator<'frame, 'metadata, T>
1263where
1264    T: DeserializeValue<'frame, 'metadata>,
1265{
1266    fn next_constant_length_elem(
1267        &mut self,
1268        element_length: usize,
1269    ) -> Option<<Self as Iterator>::Item> {
1270        self.remaining = self.remaining.checked_sub(1)?;
1271        let raw = self.slice.read_n_bytes(element_length).map_err(|err| {
1272            mk_deser_err::<Self>(
1273                self.collection_type,
1274                BuiltinDeserializationErrorKind::RawCqlBytesReadError(err),
1275            )
1276        });
1277        Some(raw.and_then(|raw| {
1278            T::deserialize(self.element_type, raw).map_err(|err| {
1279                mk_deser_err::<Self>(
1280                    self.collection_type,
1281                    VectorDeserializationErrorKind::ElementDeserializationFailed(err),
1282                )
1283            })
1284        }))
1285    }
1286
1287    fn next_variable_length_elem(&mut self) -> Option<<Self as Iterator>::Item> {
1288        self.remaining = self.remaining.checked_sub(1)?;
1289        let size = types::unsigned_vint_decode(self.slice.as_slice_mut()).map_err(|err| {
1290            mk_deser_err::<Self>(
1291                self.collection_type,
1292                BuiltinDeserializationErrorKind::RawCqlBytesReadError(
1293                    LowLevelDeserializationError::IoError(Arc::new(err)),
1294                ),
1295            )
1296        });
1297        let raw = size
1298            .and_then(|size| {
1299                size.try_into().map_err(|_| {
1300                    mk_deser_err::<Self>(
1301                        self.collection_type,
1302                        BuiltinDeserializationErrorKind::ValueOverflow,
1303                    )
1304                })
1305            })
1306            .and_then(|size: usize| {
1307                self.slice.read_n_bytes(size).map_err(|err| {
1308                    mk_deser_err::<Self>(
1309                        self.collection_type,
1310                        BuiltinDeserializationErrorKind::RawCqlBytesReadError(err),
1311                    )
1312                })
1313            });
1314
1315        Some(raw.and_then(|raw| {
1316            T::deserialize(self.element_type, raw).map_err(|err| {
1317                mk_deser_err::<Self>(
1318                    self.element_type,
1319                    VectorDeserializationErrorKind::ElementDeserializationFailed(err),
1320                )
1321            })
1322        }))
1323    }
1324}
1325
1326impl<'frame, 'metadata, T> Iterator for VectorIterator<'frame, 'metadata, T>
1327where
1328    T: DeserializeValue<'frame, 'metadata>,
1329{
1330    type Item = Result<T, DeserializationError>;
1331
1332    fn next(&mut self) -> Option<Self::Item> {
1333        match self.element_length {
1334            Some(element_length) => self.next_constant_length_elem(element_length),
1335            None => self.next_variable_length_elem(),
1336        }
1337    }
1338
1339    #[inline]
1340    fn size_hint(&self) -> (usize, Option<usize>) {
1341        (self.remaining, Some(self.remaining))
1342    }
1343
1344    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1345        if let Some(element_length) = self.element_length {
1346            // Fast path: fixed-size elements — skip n elements by advancing the frame
1347            // slice by n * element_length bytes, without deserializing each skipped element.
1348            if n >= self.remaining {
1349                self.remaining = 0;
1350                return None;
1351            }
1352            if n > 0 {
1353                let bytes_to_skip = n * element_length;
1354                if let Err(err) = self.slice.read_n_bytes(bytes_to_skip) {
1355                    // We checked that `n < self.remaining`, so this won't cause
1356                    // negative overflow.
1357                    self.remaining -= n + 1;
1358                    return Some(Err(mk_deser_err::<Self>(
1359                        self.collection_type,
1360                        BuiltinDeserializationErrorKind::RawCqlBytesReadError(err),
1361                    )));
1362                }
1363                self.remaining -= n;
1364            }
1365            self.next_constant_length_elem(element_length)
1366        } else {
1367            // Variable-length elements: fall back to the default sequential behaviour.
1368            for _ in 0..n {
1369                // Discard the item (which may be Ok or Err); only stop on exhaustion.
1370                let _ = self.next_variable_length_elem()?;
1371            }
1372            self.next_variable_length_elem()
1373        }
1374    }
1375}
1376
1377// This iterator always returns exactly `self.remaining` elements.
1378impl<'frame, 'metadata, T> ExactSizeIterator for VectorIterator<'frame, 'metadata, T> where
1379    T: DeserializeValue<'frame, 'metadata>
1380{
1381}
1382
1383/// An iterator over a CQL map.
1384#[derive(Debug, Clone)]
1385pub struct MapIterator<'frame, 'metadata, K, V> {
1386    coll_typ: &'metadata ColumnType<'metadata>,
1387    k_typ: &'metadata ColumnType<'metadata>,
1388    v_typ: &'metadata ColumnType<'metadata>,
1389    raw_iter: FixedLengthBytesSequenceIterator<'frame>,
1390    phantom_data_k: std::marker::PhantomData<K>,
1391    phantom_data_v: std::marker::PhantomData<V>,
1392}
1393
1394impl<'frame, 'metadata, K, V> MapIterator<'frame, 'metadata, K, V> {
1395    fn new(
1396        coll_typ: &'metadata ColumnType<'metadata>,
1397        k_typ: &'metadata ColumnType<'metadata>,
1398        v_typ: &'metadata ColumnType<'metadata>,
1399        count: usize,
1400        slice: FrameSlice<'frame>,
1401    ) -> Self {
1402        Self {
1403            coll_typ,
1404            k_typ,
1405            v_typ,
1406            raw_iter: FixedLengthBytesSequenceIterator::new(count, slice),
1407            phantom_data_k: std::marker::PhantomData,
1408            phantom_data_v: std::marker::PhantomData,
1409        }
1410    }
1411
1412    fn empty(
1413        coll_typ: &'metadata ColumnType<'metadata>,
1414        k_typ: &'metadata ColumnType<'metadata>,
1415        v_typ: &'metadata ColumnType<'metadata>,
1416    ) -> Self {
1417        Self {
1418            coll_typ,
1419            k_typ,
1420            v_typ,
1421            raw_iter: FixedLengthBytesSequenceIterator::empty(),
1422            phantom_data_k: std::marker::PhantomData,
1423            phantom_data_v: std::marker::PhantomData,
1424        }
1425    }
1426}
1427
1428impl<'frame, 'metadata, K, V> DeserializeValue<'frame, 'metadata>
1429    for MapIterator<'frame, 'metadata, K, V>
1430where
1431    K: DeserializeValue<'frame, 'metadata>,
1432    V: DeserializeValue<'frame, 'metadata>,
1433{
1434    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
1435        match typ {
1436            ColumnType::Collection {
1437                frozen: _,
1438                typ: CollectionType::Map(k_t, v_t),
1439            } => {
1440                <K as DeserializeValue<'frame, 'metadata>>::type_check(k_t).map_err(|err| {
1441                    mk_typck_err::<Self>(typ, MapTypeCheckErrorKind::KeyTypeCheckFailed(err))
1442                })?;
1443                <V as DeserializeValue<'frame, 'metadata>>::type_check(v_t).map_err(|err| {
1444                    mk_typck_err::<Self>(typ, MapTypeCheckErrorKind::ValueTypeCheckFailed(err))
1445                })?;
1446                Ok(())
1447            }
1448            _ => Err(mk_typck_err::<Self>(typ, MapTypeCheckErrorKind::NotMap)),
1449        }
1450    }
1451
1452    fn deserialize(
1453        typ: &'metadata ColumnType<'metadata>,
1454        v: Option<FrameSlice<'frame>>,
1455    ) -> Result<Self, DeserializationError> {
1456        let (k_typ, v_typ) = match typ {
1457            ColumnType::Collection {
1458                frozen: _,
1459                typ: CollectionType::Map(k_t, v_t),
1460            } => (k_t, v_t),
1461            _ => {
1462                unreachable!("Typecheck should have prevented this scenario!")
1463            }
1464        };
1465
1466        let mut v = if let Some(v) = v {
1467            v
1468        } else {
1469            return Ok(Self::empty(typ, k_typ, v_typ));
1470        };
1471
1472        let count = types::read_int_length(v.as_slice_mut()).map_err(|err| {
1473            mk_deser_err::<Self>(
1474                typ,
1475                MapDeserializationErrorKind::LengthDeserializationFailed(
1476                    DeserializationError::new(err),
1477                ),
1478            )
1479        })?;
1480
1481        Ok(Self::new(typ, k_typ, v_typ, 2 * count, v))
1482    }
1483}
1484
1485impl<'frame, 'metadata, K, V> Iterator for MapIterator<'frame, 'metadata, K, V>
1486where
1487    K: DeserializeValue<'frame, 'metadata>,
1488    V: DeserializeValue<'frame, 'metadata>,
1489{
1490    type Item = Result<(K, V), DeserializationError>;
1491
1492    fn next(&mut self) -> Option<Self::Item> {
1493        // Note the lack of `?` - we want each call to `next()` to consume EXACTLY two items
1494        // from the inner iterator. This is necessary for correct and precise
1495        // `size_hint`, and thus the implementation of `ExactSizeIterator`.
1496        let raw_k_result = self.raw_iter.next();
1497        let raw_v_result = self.raw_iter.next();
1498        let raw_k = match raw_k_result {
1499            Some(Ok(raw_k)) => raw_k,
1500            Some(Err(err)) => {
1501                return Some(Err(mk_deser_err::<Self>(
1502                    self.coll_typ,
1503                    BuiltinDeserializationErrorKind::RawCqlBytesReadError(err),
1504                )));
1505            }
1506            None => return None,
1507        };
1508        let raw_v = match raw_v_result {
1509            Some(Ok(raw_v)) => raw_v,
1510            Some(Err(err)) => {
1511                return Some(Err(mk_deser_err::<Self>(
1512                    self.coll_typ,
1513                    BuiltinDeserializationErrorKind::RawCqlBytesReadError(err),
1514                )));
1515            }
1516            None => return None,
1517        };
1518
1519        let do_next = || -> Result<(K, V), DeserializationError> {
1520            let k = K::deserialize(self.k_typ, raw_k).map_err(|err| {
1521                mk_deser_err::<Self>(
1522                    self.coll_typ,
1523                    MapDeserializationErrorKind::KeyDeserializationFailed(err),
1524                )
1525            })?;
1526            let v = V::deserialize(self.v_typ, raw_v).map_err(|err| {
1527                mk_deser_err::<Self>(
1528                    self.coll_typ,
1529                    MapDeserializationErrorKind::ValueDeserializationFailed(err),
1530                )
1531            })?;
1532            Ok((k, v))
1533        };
1534        Some(do_next())
1535    }
1536
1537    fn size_hint(&self) -> (usize, Option<usize>) {
1538        // Each call to `next()` consumes exactly two items from the iterator.
1539        // If, and only if, both are `Some`, this iterator returns `Some`.
1540        // This makes its item number precise, given that the inner iterator
1541        // is ExactSizeIterator.
1542        let len = self.raw_iter.len() / 2;
1543        (len, Some(len))
1544    }
1545}
1546
1547impl<'frame, 'metadata, K, V> ExactSizeIterator for MapIterator<'frame, 'metadata, K, V>
1548where
1549    K: DeserializeValue<'frame, 'metadata>,
1550    V: DeserializeValue<'frame, 'metadata>,
1551{
1552}
1553
1554impl<'frame, 'metadata, K, V> DeserializeValue<'frame, 'metadata> for BTreeMap<K, V>
1555where
1556    K: DeserializeValue<'frame, 'metadata> + Ord,
1557    V: DeserializeValue<'frame, 'metadata>,
1558{
1559    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
1560        MapIterator::<'frame, 'metadata, K, V>::type_check(typ)
1561            .map_err(typck_error_replace_rust_name::<Self>)
1562    }
1563
1564    fn deserialize(
1565        typ: &'metadata ColumnType<'metadata>,
1566        v: Option<FrameSlice<'frame>>,
1567    ) -> Result<Self, DeserializationError> {
1568        MapIterator::<'frame, 'metadata, K, V>::deserialize(typ, v)
1569            .and_then(|it| it.collect::<Result<_, DeserializationError>>())
1570            .map_err(deser_error_replace_rust_name::<Self>)
1571    }
1572}
1573
1574impl<'frame, 'metadata, K, V, S> DeserializeValue<'frame, 'metadata> for HashMap<K, V, S>
1575where
1576    K: DeserializeValue<'frame, 'metadata> + Eq + Hash,
1577    V: DeserializeValue<'frame, 'metadata>,
1578    S: BuildHasher + Default + 'frame,
1579{
1580    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
1581        MapIterator::<'frame, 'metadata, K, V>::type_check(typ)
1582            .map_err(typck_error_replace_rust_name::<Self>)
1583    }
1584
1585    fn deserialize(
1586        typ: &'metadata ColumnType<'metadata>,
1587        v: Option<FrameSlice<'frame>>,
1588    ) -> Result<Self, DeserializationError> {
1589        MapIterator::<'frame, 'metadata, K, V>::deserialize(typ, v)
1590            .and_then(|it| it.collect::<Result<_, DeserializationError>>())
1591            .map_err(deser_error_replace_rust_name::<Self>)
1592    }
1593}
1594
1595// tuples
1596
1597// Implements tuple deserialization.
1598// The generated impl expects that the serialized data contains exactly the given amount of values.
1599macro_rules! impl_tuple {
1600    ($($Ti:ident),*; $($idx:literal),*; $($idf:ident),*) => {
1601        impl<'frame, 'metadata, $($Ti),*> DeserializeValue<'frame, 'metadata> for ($($Ti,)*)
1602        where
1603            $($Ti: DeserializeValue<'frame, 'metadata>),*
1604        {
1605            fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
1606                const TUPLE_LEN: usize = (&[$($idx),*] as &[i32]).len();
1607                let [$($idf),*] = ensure_tuple_type::<($($Ti,)*), TUPLE_LEN>(typ)?;
1608                $(
1609                    <$Ti>::type_check($idf).map_err(|err| mk_typck_err::<Self>(
1610                        typ,
1611                        TupleTypeCheckErrorKind::FieldTypeCheckFailed {
1612                            position: $idx,
1613                            err,
1614                        }
1615                    ))?;
1616                )*
1617                Ok(())
1618            }
1619
1620            fn deserialize(typ: &'metadata ColumnType<'metadata>, v: Option<FrameSlice<'frame>>) -> Result<Self, DeserializationError> {
1621                const TUPLE_LEN: usize = (&[$($idx),*] as &[i32]).len();
1622                // Safety: we are allowed to assume that type_check() was already called.
1623                let [$($idf),*] = ensure_tuple_type::<($($Ti,)*), TUPLE_LEN>(typ)
1624                    .expect("Type check should have prevented this!");
1625
1626                // Ignore the warning for the zero-sized tuple
1627                #[allow(unused)]
1628                let mut v = ensure_not_null_frame_slice::<Self>(typ, v)?;
1629                let ret = (
1630                    $(
1631                        {
1632                            let cql_bytes = if v.is_empty() {
1633                                // Special case: if there are no bytes left to read, consider the tuple element as null.
1634                                // This is needed to handle tuples with fewer elements than expected
1635                                // (see https://github.com/scylladb/scylla-rust-driver/issues/1452 for context).
1636                                None
1637                            } else {
1638                                v.read_cql_bytes().map_err(|err| DeserializationError::new(err))?
1639                            };
1640
1641                            <$Ti>::deserialize($idf, cql_bytes)
1642                                .map_err(|err| mk_deser_err::<Self>(
1643                                    typ,
1644                                    TupleDeserializationErrorKind::FieldDeserializationFailed {
1645                                        position: $idx,
1646                                        err,
1647                                    }
1648                                )
1649                            )?
1650                        },
1651                    )*
1652                );
1653                Ok(ret)
1654            }
1655        }
1656    }
1657}
1658
1659// Implements tuple deserialization for all tuple sizes up to predefined size.
1660// Accepts 3 lists, (see usage below the definition):
1661// - type parameters for the consecutive fields,
1662// - indices of the consecutive fields,
1663// - consecutive names for variables corresponding to each field.
1664//
1665// The idea is to recursively build prefixes of those lists (starting with an empty prefix)
1666// and for each prefix, implement deserialization for generic tuple represented by it.
1667// The < > brackets aid syntactically to separate the prefixes (positioned inside them)
1668// from the remaining suffixes (positioned beyond them).
1669macro_rules! impl_tuple_multiple {
1670    // The entry point to the macro.
1671    // Begins with implementing deserialization for (), then proceeds to the main recursive call.
1672    ($($Ti:ident),*; $($idx:literal),*; $($idf:ident),*) => {
1673        impl_tuple!(;;);
1674        impl_tuple_multiple!(
1675            $($Ti),* ; < > ;
1676            $($idx),*; < > ;
1677            $($idf),*; < >
1678        );
1679    };
1680
1681    // The termination condition. No more fields given to extend the tuple with.
1682    (;< $($Ti:ident,)* >;;< $($idx:literal,)* >;;< $($idf:ident,)* >) => {};
1683
1684    // The recursion. Upon each call, a new field is appended to the tuple
1685    // and deserialization is implemented for it.
1686    (
1687        $T_head:ident $(,$T_suffix:ident)*; < $($T_prefix:ident,)* > ;
1688        $idx_head:literal $(,$idx_suffix:literal)*; < $($idx_prefix:literal,)* >;
1689        $idf_head:ident $(,$idf_suffix:ident)* ; <$($idf_prefix:ident,)*>
1690    ) => {
1691        impl_tuple!(
1692            $($T_prefix,)* $T_head;
1693            $($idx_prefix, )* $idx_head;
1694            $($idf_prefix, )* $idf_head
1695        );
1696        impl_tuple_multiple!(
1697            $($T_suffix),* ; < $($T_prefix,)* $T_head, > ;
1698            $($idx_suffix),*; < $($idx_prefix, )* $idx_head, > ;
1699            $($idf_suffix),*; < $($idf_prefix, )* $idf_head, >
1700        );
1701    }
1702}
1703
1704pub(super) use impl_tuple_multiple;
1705
1706// Implements tuple deserialization for all tuple sizes up to 16.
1707impl_tuple_multiple!(
1708    T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15;
1709    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15;
1710    t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15
1711);
1712
1713// udts
1714
1715/// An iterator over fields of a User Defined Type.
1716///
1717/// # Note
1718///
1719/// A serialized UDT will generally have one value for each field, but it is
1720/// allowed to have fewer. This iterator differentiates null values
1721/// from non-existent values in the following way:
1722///
1723/// - `None` - missing from the serialized form
1724/// - `Some(None)` - present, but null
1725/// - `Some(Some(...))` - non-null, present value
1726#[derive(Debug, Clone)]
1727pub struct UdtIterator<'frame, 'metadata> {
1728    all_fields: &'metadata [(Cow<'metadata, str>, ColumnType<'metadata>)],
1729    type_name: &'metadata str,
1730    keyspace: &'metadata str,
1731    remaining_fields: &'metadata [(Cow<'metadata, str>, ColumnType<'metadata>)],
1732    raw_iter: BytesSequenceIterator<'frame>,
1733}
1734
1735impl<'frame, 'metadata> UdtIterator<'frame, 'metadata> {
1736    fn new(
1737        fields: &'metadata [(Cow<'metadata, str>, ColumnType<'metadata>)],
1738        type_name: &'metadata str,
1739        keyspace: &'metadata str,
1740        slice: FrameSlice<'frame>,
1741    ) -> Self {
1742        Self {
1743            all_fields: fields,
1744            remaining_fields: fields,
1745            type_name,
1746            keyspace,
1747            raw_iter: BytesSequenceIterator::new(slice),
1748        }
1749    }
1750
1751    /// Returns remaining (i.e., not yet deserialized) fields of the UDT.
1752    #[inline]
1753    pub fn fields(&self) -> &'metadata [(Cow<'metadata, str>, ColumnType<'metadata>)] {
1754        self.remaining_fields
1755    }
1756}
1757
1758impl<'frame, 'metadata> DeserializeValue<'frame, 'metadata> for UdtIterator<'frame, 'metadata> {
1759    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
1760        match typ {
1761            ColumnType::UserDefinedType { .. } => Ok(()),
1762            _ => Err(mk_typck_err::<Self>(typ, UdtTypeCheckErrorKind::NotUdt)),
1763        }
1764    }
1765
1766    fn deserialize(
1767        typ: &'metadata ColumnType<'metadata>,
1768        v: Option<FrameSlice<'frame>>,
1769    ) -> Result<Self, DeserializationError> {
1770        let v = ensure_not_null_frame_slice::<Self>(typ, v)?;
1771        let (fields, type_name, keyspace) = match typ {
1772            ColumnType::UserDefinedType {
1773                definition: udt, ..
1774            } => (
1775                udt.field_types.as_ref(),
1776                udt.name.as_ref(),
1777                udt.keyspace.as_ref(),
1778            ),
1779            _ => {
1780                unreachable!("Typecheck should have prevented this scenario!")
1781            }
1782        };
1783        Ok(Self::new(fields, type_name, keyspace, v))
1784    }
1785}
1786
1787impl<'frame, 'metadata> Iterator for UdtIterator<'frame, 'metadata> {
1788    type Item = (
1789        &'metadata (Cow<'metadata, str>, ColumnType<'metadata>),
1790        Result<Option<Option<FrameSlice<'frame>>>, DeserializationError>,
1791    );
1792
1793    fn next(&mut self) -> Option<Self::Item> {
1794        let (head, fields) = self.remaining_fields.split_first()?;
1795        self.remaining_fields = fields;
1796        let raw_res = match self.raw_iter.next() {
1797            // The field is there and it was parsed correctly
1798            Some(Ok(raw)) => Ok(Some(raw)),
1799
1800            // There were some bytes but they didn't parse as correct field value
1801            Some(Err(err)) => Err(mk_deser_err::<Self>(
1802                &ColumnType::UserDefinedType {
1803                    frozen: false,
1804                    definition: Arc::new(UserDefinedType {
1805                        name: self.type_name.into(),
1806                        keyspace: self.keyspace.into(),
1807                        field_types: self.all_fields.to_owned(),
1808                    }),
1809                },
1810                BuiltinDeserializationErrorKind::RawCqlBytesReadError(err),
1811            )),
1812
1813            // The field is just missing from the serialized form
1814            None => Ok(None),
1815        };
1816        Some((head, raw_res))
1817    }
1818
1819    fn size_hint(&self) -> (usize, Option<usize>) {
1820        // The iterator yields exactly one item per remaining field, regardless of whether
1821        // the serialized form contains a value for that field or not (missing fields are
1822        // reported as `Ok(None)`).
1823        let len = self.remaining_fields.len();
1824        (len, Some(len))
1825    }
1826}
1827
1828// The iterator yields exactly one item per remaining field, regardless of whether
1829// the serialized form contains a value for that field or not (missing fields are
1830// reported as `Ok(None)`).
1831impl<'frame, 'metadata> ExactSizeIterator for UdtIterator<'frame, 'metadata> {}
1832
1833// Container implementations
1834
1835impl<'frame, 'metadata, T: DeserializeValue<'frame, 'metadata>> DeserializeValue<'frame, 'metadata>
1836    for Box<T>
1837{
1838    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
1839        T::type_check(typ).map_err(typck_error_replace_rust_name::<Self>)
1840    }
1841
1842    fn deserialize(
1843        typ: &'metadata ColumnType<'metadata>,
1844        v: Option<FrameSlice<'frame>>,
1845    ) -> Result<Self, DeserializationError> {
1846        T::deserialize(typ, v)
1847            .map(Box::new)
1848            .map_err(deser_error_replace_rust_name::<Self>)
1849    }
1850}
1851
1852impl<'frame, 'metadata, T: DeserializeValue<'frame, 'metadata>> DeserializeValue<'frame, 'metadata>
1853    for Arc<T>
1854{
1855    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
1856        T::type_check(typ).map_err(typck_error_replace_rust_name::<Self>)
1857    }
1858
1859    fn deserialize(
1860        typ: &'metadata ColumnType<'metadata>,
1861        v: Option<FrameSlice<'frame>>,
1862    ) -> Result<Self, DeserializationError> {
1863        T::deserialize(typ, v)
1864            .map(Arc::new)
1865            .map_err(deser_error_replace_rust_name::<Self>)
1866    }
1867}
1868
1869impl<'frame, 'metadata, T: 'frame + ToOwned + ?Sized> DeserializeValue<'frame, 'metadata>
1870    for Cow<'frame, T>
1871where
1872    &'frame T: DeserializeValue<'frame, 'metadata>,
1873{
1874    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
1875        <&T>::type_check(typ).map_err(typck_error_replace_rust_name::<Self>)
1876    }
1877
1878    fn deserialize(
1879        typ: &'metadata ColumnType<'metadata>,
1880        v: Option<FrameSlice<'frame>>,
1881    ) -> Result<Self, DeserializationError> {
1882        <&T>::deserialize(typ, v)
1883            .map(Cow::Borrowed)
1884            .map_err(deser_error_replace_rust_name::<Self>)
1885    }
1886}
1887
1888// Special cases for Box<str> and Arc<str>
1889// The generic implementations above don't work for str. This is because
1890// DeserializeValue is implemented for &str, but not for str. We can't change this:
1891// the type for DeserializeValue must be Sized because it is returned from deserialize method.
1892
1893impl<'frame, 'metadata> DeserializeValue<'frame, 'metadata> for Box<str> {
1894    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
1895        <String as DeserializeValue>::type_check(typ).map_err(typck_error_replace_rust_name::<Self>)
1896    }
1897
1898    fn deserialize(
1899        typ: &'metadata ColumnType<'metadata>,
1900        v: Option<FrameSlice<'frame>>,
1901    ) -> Result<Self, DeserializationError> {
1902        String::deserialize(typ, v)
1903            .map(String::into_boxed_str)
1904            .map_err(deser_error_replace_rust_name::<Self>)
1905    }
1906}
1907
1908impl<'frame, 'metadata> DeserializeValue<'frame, 'metadata> for Arc<str> {
1909    fn type_check(typ: &ColumnType) -> Result<(), TypeCheckError> {
1910        <&str as DeserializeValue>::type_check(typ).map_err(typck_error_replace_rust_name::<Self>)
1911    }
1912
1913    fn deserialize(
1914        typ: &'metadata ColumnType<'metadata>,
1915        v: Option<FrameSlice<'frame>>,
1916    ) -> Result<Self, DeserializationError> {
1917        <&str as DeserializeValue>::deserialize(typ, v)
1918            .map(Into::<Arc<str>>::into)
1919            .map_err(deser_error_replace_rust_name::<Self>)
1920    }
1921}
1922
1923// Utilities
1924
1925fn ensure_not_null_frame_slice<'frame, T>(
1926    typ: &ColumnType,
1927    v: Option<FrameSlice<'frame>>,
1928) -> Result<FrameSlice<'frame>, DeserializationError> {
1929    v.ok_or_else(|| mk_deser_err::<T>(typ, BuiltinDeserializationErrorKind::ExpectedNonNull))
1930}
1931
1932fn ensure_not_null_slice<'frame, T>(
1933    typ: &ColumnType,
1934    v: Option<FrameSlice<'frame>>,
1935) -> Result<&'frame [u8], DeserializationError> {
1936    ensure_not_null_frame_slice::<T>(typ, v).map(|frame_slice| frame_slice.as_slice())
1937}
1938
1939fn ensure_not_null_owned<T>(
1940    typ: &ColumnType,
1941    v: Option<FrameSlice>,
1942) -> Result<Bytes, DeserializationError> {
1943    ensure_not_null_frame_slice::<T>(typ, v).map(|frame_slice| frame_slice.to_bytes())
1944}
1945
1946fn ensure_exact_length<'frame, T, const SIZE: usize>(
1947    typ: &ColumnType,
1948    v: &'frame [u8],
1949) -> Result<&'frame [u8; SIZE], DeserializationError> {
1950    v.try_into().map_err(|_| {
1951        mk_deser_err::<T>(
1952            typ,
1953            BuiltinDeserializationErrorKind::ByteLengthMismatch {
1954                expected: SIZE,
1955                got: v.len(),
1956            },
1957        )
1958    })
1959}
1960
1961fn ensure_tuple_type<'a, 'b, T, const SIZE: usize>(
1962    typ: &'b ColumnType<'a>,
1963) -> Result<&'b [ColumnType<'a>; SIZE], TypeCheckError> {
1964    if let ColumnType::Tuple(typs_v) = typ {
1965        typs_v.as_slice().try_into().map_err(|_| {
1966            BuiltinTypeCheckErrorKind::TupleError(TupleTypeCheckErrorKind::WrongElementCount {
1967                rust_type_el_count: SIZE,
1968                cql_type_el_count: typs_v.len(),
1969            })
1970        })
1971    } else {
1972        Err(BuiltinTypeCheckErrorKind::TupleError(
1973            TupleTypeCheckErrorKind::NotTuple,
1974        ))
1975    }
1976    .map_err(|kind| mk_typck_err::<T>(typ, kind))
1977}
1978
1979// Helper iterators
1980
1981/// Iterates over a sequence of `[bytes]` items from a frame subslice, expecting
1982/// a particular number of items.
1983///
1984/// The iterator does not consider it to be an error if there are some bytes
1985/// remaining in the slice after parsing requested amount of items.
1986#[derive(Clone, Copy, Debug)]
1987pub struct FixedLengthBytesSequenceIterator<'frame> {
1988    slice: FrameSlice<'frame>,
1989    remaining: usize,
1990}
1991
1992impl<'frame> FixedLengthBytesSequenceIterator<'frame> {
1993    fn new(count: usize, slice: FrameSlice<'frame>) -> Self {
1994        Self {
1995            slice,
1996            remaining: count,
1997        }
1998    }
1999
2000    fn empty() -> Self {
2001        Self {
2002            slice: FrameSlice::new_empty(),
2003            remaining: 0,
2004        }
2005    }
2006}
2007
2008impl<'frame> Iterator for FixedLengthBytesSequenceIterator<'frame> {
2009    type Item = Result<Option<FrameSlice<'frame>>, LowLevelDeserializationError>;
2010
2011    fn next(&mut self) -> Option<Self::Item> {
2012        self.remaining = self.remaining.checked_sub(1)?;
2013        Some(self.slice.read_cql_bytes())
2014    }
2015
2016    // Always yields exactly the requested number of elements.
2017    // Some of them may be errors, but it is irrelevant for `size_hint`.
2018    fn size_hint(&self) -> (usize, Option<usize>) {
2019        (self.remaining, Some(self.remaining))
2020    }
2021}
2022
2023// Always yields exactly the requested number of elements.
2024// Some of them may be errors, but it is irrelevant here.
2025impl<'frame> ExactSizeIterator for FixedLengthBytesSequenceIterator<'frame> {}
2026
2027/// Iterates over a sequence of `[bytes]` items from a frame subslice.
2028///
2029/// The `[bytes]` items are parsed until the end of subslice is reached.
2030#[derive(Clone, Copy, Debug)]
2031pub struct BytesSequenceIterator<'frame> {
2032    slice: FrameSlice<'frame>,
2033}
2034
2035impl<'frame> BytesSequenceIterator<'frame> {
2036    fn new(slice: FrameSlice<'frame>) -> Self {
2037        Self { slice }
2038    }
2039}
2040
2041impl<'frame> From<FrameSlice<'frame>> for BytesSequenceIterator<'frame> {
2042    #[inline]
2043    fn from(slice: FrameSlice<'frame>) -> Self {
2044        Self::new(slice)
2045    }
2046}
2047
2048impl<'frame> Iterator for BytesSequenceIterator<'frame> {
2049    type Item = Result<Option<FrameSlice<'frame>>, LowLevelDeserializationError>;
2050
2051    fn next(&mut self) -> Option<Self::Item> {
2052        if self.slice.as_slice().is_empty() {
2053            None
2054        } else {
2055            Some(self.slice.read_cql_bytes())
2056        }
2057    }
2058}
2059
2060// Error facilities
2061
2062/// Type checking of one of the built-in types failed.
2063#[derive(Debug, Error, Clone)]
2064#[error("Failed to type check Rust type {rust_name} against CQL type {cql_type:?}: {kind}")]
2065pub struct BuiltinTypeCheckError {
2066    /// Name of the Rust type being deserialized.
2067    pub rust_name: &'static str,
2068
2069    /// The CQL type that the Rust type was being deserialized from.
2070    pub cql_type: ColumnType<'static>,
2071
2072    /// Detailed information about the failure.
2073    pub kind: BuiltinTypeCheckErrorKind,
2074}
2075
2076/// Creates a [`BuiltinTypeCheckError`] with the given kind.
2077pub fn mk_typck_err<T>(
2078    cql_type: &ColumnType,
2079    kind: impl Into<BuiltinTypeCheckErrorKind>,
2080) -> TypeCheckError {
2081    mk_typck_err_named(std::any::type_name::<T>(), cql_type, kind)
2082}
2083
2084fn mk_typck_err_named(
2085    name: &'static str,
2086    cql_type: &ColumnType,
2087    kind: impl Into<BuiltinTypeCheckErrorKind>,
2088) -> TypeCheckError {
2089    TypeCheckError::new(BuiltinTypeCheckError {
2090        rust_name: name,
2091        cql_type: cql_type.clone().into_owned(),
2092        kind: kind.into(),
2093    })
2094}
2095
2096macro_rules! exact_type_check {
2097    ($typ:ident, $($cql:tt),*) => {
2098        match $typ {
2099            $(ColumnType::Native(NativeType::$cql))|* => {},
2100            _ => return Err(mk_typck_err::<Self>(
2101                $typ,
2102                BuiltinTypeCheckErrorKind::MismatchedType {
2103                    expected: &[$(ColumnType::Native(NativeType::$cql)),*],
2104                }
2105            ))
2106        }
2107    };
2108}
2109use exact_type_check;
2110
2111/// Describes why type checking some of the built-in types failed.
2112#[derive(Debug, Clone)]
2113#[non_exhaustive]
2114pub enum BuiltinTypeCheckErrorKind {
2115    /// Expected one from a list of particular types.
2116    MismatchedType {
2117        /// The list of types that the Rust type can deserialize from.
2118        expected: &'static [ColumnType<'static>],
2119    },
2120
2121    /// A type check failure specific to a CQL set or list.
2122    SetOrListError(SetOrListTypeCheckErrorKind),
2123
2124    /// A type check failure specific to a CQL vector.
2125    VectorError(VectorTypeCheckErrorKind),
2126
2127    /// A type check failure specific to a CQL map.
2128    MapError(MapTypeCheckErrorKind),
2129
2130    /// A type check failure specific to a CQL tuple.
2131    TupleError(TupleTypeCheckErrorKind),
2132
2133    /// A type check failure specific to a CQL UDT.
2134    UdtError(UdtTypeCheckErrorKind),
2135
2136    /// A type check detected type not deserializable to a vector.
2137    NotDeserializableToVec,
2138}
2139
2140impl From<SetOrListTypeCheckErrorKind> for BuiltinTypeCheckErrorKind {
2141    #[inline]
2142    fn from(value: SetOrListTypeCheckErrorKind) -> Self {
2143        BuiltinTypeCheckErrorKind::SetOrListError(value)
2144    }
2145}
2146
2147impl From<VectorTypeCheckErrorKind> for BuiltinTypeCheckErrorKind {
2148    #[inline]
2149    fn from(value: VectorTypeCheckErrorKind) -> Self {
2150        BuiltinTypeCheckErrorKind::VectorError(value)
2151    }
2152}
2153
2154impl From<MapTypeCheckErrorKind> for BuiltinTypeCheckErrorKind {
2155    #[inline]
2156    fn from(value: MapTypeCheckErrorKind) -> Self {
2157        BuiltinTypeCheckErrorKind::MapError(value)
2158    }
2159}
2160
2161impl From<TupleTypeCheckErrorKind> for BuiltinTypeCheckErrorKind {
2162    #[inline]
2163    fn from(value: TupleTypeCheckErrorKind) -> Self {
2164        BuiltinTypeCheckErrorKind::TupleError(value)
2165    }
2166}
2167
2168impl From<UdtTypeCheckErrorKind> for BuiltinTypeCheckErrorKind {
2169    #[inline]
2170    fn from(value: UdtTypeCheckErrorKind) -> Self {
2171        BuiltinTypeCheckErrorKind::UdtError(value)
2172    }
2173}
2174
2175impl Display for BuiltinTypeCheckErrorKind {
2176    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2177        match self {
2178            BuiltinTypeCheckErrorKind::MismatchedType { expected } => {
2179                write!(f, "expected one of the CQL types: {expected:?}")
2180            }
2181            BuiltinTypeCheckErrorKind::SetOrListError(err) => err.fmt(f),
2182            BuiltinTypeCheckErrorKind::VectorError(err) => err.fmt(f),
2183            BuiltinTypeCheckErrorKind::MapError(err) => err.fmt(f),
2184            BuiltinTypeCheckErrorKind::TupleError(err) => err.fmt(f),
2185            BuiltinTypeCheckErrorKind::UdtError(err) => err.fmt(f),
2186            BuiltinTypeCheckErrorKind::NotDeserializableToVec => {
2187                f.write_str("the CQL type is not deserializable to a vector")
2188            }
2189        }
2190    }
2191}
2192
2193/// Describes why type checking of a set or list type failed.
2194#[derive(Debug, Clone)]
2195#[non_exhaustive]
2196pub enum SetOrListTypeCheckErrorKind {
2197    /// The CQL type is neither a set not a list.
2198    NotSetOrList,
2199    /// The CQL type is not a set.
2200    NotSet,
2201    /// Incompatible element types.
2202    ElementTypeCheckFailed(TypeCheckError),
2203}
2204
2205impl Display for SetOrListTypeCheckErrorKind {
2206    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2207        match self {
2208            SetOrListTypeCheckErrorKind::NotSetOrList => {
2209                f.write_str("the CQL type the Rust type was attempted to be type checked against was neither a set nor a list")
2210            }
2211            SetOrListTypeCheckErrorKind::NotSet => {
2212                f.write_str("the CQL type the Rust type was attempted to be type checked against was not a set")
2213            }
2214            SetOrListTypeCheckErrorKind::ElementTypeCheckFailed(err) => {
2215                write!(f, "the set or list element types between the CQL type and the Rust type failed to type check against each other: {err}")
2216            }
2217        }
2218    }
2219}
2220
2221/// Describes why type checking a vector type failed.
2222#[derive(Error, Debug, Clone)]
2223#[non_exhaustive]
2224pub enum VectorTypeCheckErrorKind {
2225    /// The CQL type is not a vector.
2226    #[error("the CQL type the Rust type was attempted to be type checked against was not a vector")]
2227    NotVector,
2228    /// Incompatible element types.
2229    #[error(
2230        "the vector element types between the CQL type and the Rust type failed to type check against each other: {0}"
2231    )]
2232    ElementTypeCheckFailed(TypeCheckError),
2233}
2234
2235/// Describes why type checking of a map type failed.
2236#[derive(Debug, Clone)]
2237#[non_exhaustive]
2238pub enum MapTypeCheckErrorKind {
2239    /// The CQL type is not a map.
2240    NotMap,
2241    /// Incompatible key types.
2242    KeyTypeCheckFailed(TypeCheckError),
2243    /// Incompatible value types.
2244    ValueTypeCheckFailed(TypeCheckError),
2245}
2246
2247impl Display for MapTypeCheckErrorKind {
2248    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2249        match self {
2250            MapTypeCheckErrorKind::NotMap => {
2251                f.write_str("the CQL type the Rust type was attempted to be type checked against was neither a map")
2252            }
2253            MapTypeCheckErrorKind::KeyTypeCheckFailed(err) => {
2254                write!(f, "the map key types between the CQL type and the Rust type failed to type check against each other: {err}")
2255            },
2256            MapTypeCheckErrorKind::ValueTypeCheckFailed(err) => {
2257                write!(f, "the map value types between the CQL type and the Rust type failed to type check against each other: {err}")
2258            },
2259        }
2260    }
2261}
2262
2263/// Describes why type checking of a tuple failed.
2264#[derive(Debug, Clone)]
2265#[non_exhaustive]
2266pub enum TupleTypeCheckErrorKind {
2267    /// The CQL type is not a tuple.
2268    NotTuple,
2269
2270    /// The tuple has the wrong element count.
2271    WrongElementCount {
2272        /// The number of elements that the Rust tuple has.
2273        rust_type_el_count: usize,
2274
2275        /// The number of elements that the CQL tuple type has.
2276        cql_type_el_count: usize,
2277    },
2278
2279    /// The CQL type and the Rust type of a tuple field failed to type check against each other.
2280    FieldTypeCheckFailed {
2281        /// The index of the field whose type check failed.
2282        position: usize,
2283
2284        /// The type check error that occurred.
2285        err: TypeCheckError,
2286    },
2287}
2288
2289impl Display for TupleTypeCheckErrorKind {
2290    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2291        match self {
2292            TupleTypeCheckErrorKind::NotTuple => write!(
2293                f,
2294                "the CQL type the tuple was attempted to be serialized to is not a tuple"
2295            ),
2296            TupleTypeCheckErrorKind::WrongElementCount {
2297                rust_type_el_count,
2298                cql_type_el_count,
2299            } => write!(
2300                f,
2301                "wrong tuple element count: CQL type has {cql_type_el_count}, the Rust tuple has {rust_type_el_count}"
2302            ),
2303
2304            TupleTypeCheckErrorKind::FieldTypeCheckFailed { position, err } => write!(
2305                f,
2306                "the CQL type and the Rust type of the tuple field {position} failed to type check against each other: {err}"
2307            ),
2308        }
2309    }
2310}
2311
2312/// Describes why type checking of a user defined type failed.
2313#[derive(Debug, Clone)]
2314#[non_exhaustive]
2315pub enum UdtTypeCheckErrorKind {
2316    /// The CQL type is not a user defined type.
2317    NotUdt,
2318
2319    /// The CQL UDT type does not have some fields that is required in the Rust struct.
2320    ValuesMissingForUdtFields {
2321        /// Names of fields that the Rust struct requires but are missing in the CQL UDT.
2322        field_names: Vec<&'static str>,
2323    },
2324
2325    /// A different field name was expected at given position.
2326    FieldNameMismatch {
2327        /// Index of the field in the Rust struct.
2328        position: usize,
2329
2330        /// The name of the Rust field.
2331        rust_field_name: String,
2332
2333        /// The name of the CQL UDT field.
2334        db_field_name: String,
2335    },
2336
2337    /// UDT contains an excess field, which does not correspond to any Rust struct's field.
2338    ExcessFieldInUdt {
2339        /// The name of the CQL UDT field.
2340        db_field_name: String,
2341    },
2342
2343    /// Duplicated field in serialized data.
2344    DuplicatedField {
2345        /// The name of the duplicated field.
2346        field_name: String,
2347    },
2348
2349    /// Fewer fields present in the UDT than required by the Rust type.
2350    TooFewFields {
2351        // TODO: decide whether we are OK with restricting to `&'static str` here.
2352        required_fields: Vec<&'static str>,
2353        present_fields: Vec<String>,
2354    },
2355
2356    /// Type check failed between UDT and Rust type field.
2357    FieldTypeCheckFailed {
2358        /// The name of the field whose type check failed.
2359        field_name: String,
2360
2361        /// Inner type check error that occurred.
2362        err: TypeCheckError,
2363    },
2364}
2365
2366impl Display for UdtTypeCheckErrorKind {
2367    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2368        match self {
2369            UdtTypeCheckErrorKind::NotUdt => write!(
2370                f,
2371                "the CQL type the Rust type was attempted to be type checked against is not a UDT"
2372            ),
2373            UdtTypeCheckErrorKind::ValuesMissingForUdtFields { field_names } => {
2374                write!(
2375                    f,
2376                    "the fields {field_names:?} are missing from the DB data but are required by the Rust type"
2377                )
2378            }
2379            UdtTypeCheckErrorKind::FieldNameMismatch {
2380                rust_field_name,
2381                db_field_name,
2382                position,
2383            } => write!(
2384                f,
2385                "expected field with name {db_field_name} at position {position}, but the Rust field name is {rust_field_name}"
2386            ),
2387            UdtTypeCheckErrorKind::ExcessFieldInUdt { db_field_name } => write!(
2388                f,
2389                "UDT contains an excess field {db_field_name}, which does not correspond to any Rust struct's field."
2390            ),
2391            UdtTypeCheckErrorKind::DuplicatedField { field_name } => write!(
2392                f,
2393                "field {field_name} occurs more than once in CQL UDT type"
2394            ),
2395            UdtTypeCheckErrorKind::TooFewFields {
2396                required_fields,
2397                present_fields,
2398            } => write!(
2399                f,
2400                "fewer fields present in the UDT than required by the Rust type: UDT has {present_fields:?}, Rust type requires {required_fields:?}",
2401            ),
2402            UdtTypeCheckErrorKind::FieldTypeCheckFailed { field_name, err } => write!(
2403                f,
2404                "the UDT field {field_name} types between the CQL type and the Rust type failed to type check against each other: {err}"
2405            ),
2406        }
2407    }
2408}
2409
2410/// Deserialization of one of the built-in types failed.
2411#[derive(Debug, Error, Clone)]
2412#[error("Failed to deserialize Rust type {rust_name} from CQL type {cql_type:?}: {kind}")]
2413pub struct BuiltinDeserializationError {
2414    /// Name of the Rust type being deserialized.
2415    pub rust_name: &'static str,
2416
2417    /// The CQL type that the Rust type was being deserialized from.
2418    pub cql_type: ColumnType<'static>,
2419
2420    /// Detailed information about the failure.
2421    pub kind: BuiltinDeserializationErrorKind,
2422}
2423
2424/// Creates a [`BuiltinDeserializationError`] with the given kind.
2425pub fn mk_deser_err<T>(
2426    cql_type: &ColumnType,
2427    kind: impl Into<BuiltinDeserializationErrorKind>,
2428) -> DeserializationError {
2429    mk_deser_err_named(std::any::type_name::<T>(), cql_type, kind)
2430}
2431
2432fn mk_deser_err_named(
2433    name: &'static str,
2434    cql_type: &ColumnType,
2435    kind: impl Into<BuiltinDeserializationErrorKind>,
2436) -> DeserializationError {
2437    DeserializationError::new(BuiltinDeserializationError {
2438        rust_name: name,
2439        cql_type: cql_type.clone().into_owned(),
2440        kind: kind.into(),
2441    })
2442}
2443
2444/// Describes why deserialization of some of the built-in types failed.
2445#[derive(Debug, Clone)]
2446#[non_exhaustive]
2447pub enum BuiltinDeserializationErrorKind {
2448    /// Failed to deserialize one of date's fields.
2449    BadDate {
2450        date_field: &'static str,
2451        err: LowLevelDeserializationError,
2452    },
2453
2454    /// Failed to deserialize decimal's scale.
2455    BadDecimalScale(LowLevelDeserializationError),
2456
2457    /// Failed to deserialize raw bytes of cql value.
2458    RawCqlBytesReadError(LowLevelDeserializationError),
2459
2460    /// Expected non-null value, got null.
2461    ExpectedNonNull,
2462
2463    /// The length of read value in bytes is different than expected for the Rust type.
2464    ByteLengthMismatch { expected: usize, got: usize },
2465
2466    /// Expected valid ASCII string.
2467    ExpectedAscii,
2468
2469    /// Invalid UTF-8 string.
2470    InvalidUtf8(std::str::Utf8Error),
2471
2472    /// The read value is out of range supported by the Rust type.
2473    // TODO: consider storing additional info here (what exactly did not fit and why)
2474    ValueOverflow,
2475
2476    /// The length of read value in bytes is not suitable for IP address.
2477    BadInetLength { got: usize },
2478
2479    /// A deserialization failure specific to a CQL set or list.
2480    SetOrListError(SetOrListDeserializationErrorKind),
2481
2482    /// A deserialization failure specific to a CQL vector.
2483    VectorError(VectorDeserializationErrorKind),
2484
2485    /// A deserialization failure specific to a CQL map.
2486    MapError(MapDeserializationErrorKind),
2487
2488    /// A deserialization failure specific to a CQL tuple.
2489    TupleError(TupleDeserializationErrorKind),
2490
2491    /// A deserialization failure specific to a CQL UDT.
2492    UdtError(UdtDeserializationErrorKind),
2493
2494    /// Deserialization of this CQL type is not supported by the driver.
2495    Unsupported,
2496}
2497
2498impl Display for BuiltinDeserializationErrorKind {
2499    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2500        match self {
2501            BuiltinDeserializationErrorKind::BadDate { date_field, err } => write!(
2502                f,
2503                "malformed {date_field} during 'date' deserialization: {err}"
2504            ),
2505            BuiltinDeserializationErrorKind::BadDecimalScale(err) => {
2506                write!(f, "malformed decimal's scale: {err}")
2507            }
2508            BuiltinDeserializationErrorKind::RawCqlBytesReadError(err) => {
2509                write!(f, "failed to read raw cql value bytes: {err}")
2510            }
2511            BuiltinDeserializationErrorKind::ExpectedNonNull => {
2512                f.write_str("expected a non-null value, got null")
2513            }
2514            BuiltinDeserializationErrorKind::ByteLengthMismatch { expected, got } => {
2515                write!(f, "the CQL type requires {expected} bytes, but got {got}",)
2516            }
2517            BuiltinDeserializationErrorKind::ExpectedAscii => {
2518                f.write_str("expected a valid ASCII string")
2519            }
2520            BuiltinDeserializationErrorKind::InvalidUtf8(err) => err.fmt(f),
2521            BuiltinDeserializationErrorKind::ValueOverflow => {
2522                // TODO: consider storing Arc<dyn Display/Debug> of the offending value
2523                // inside this variant for debug purposes.
2524                f.write_str("read value is out of representable range")
2525            }
2526            BuiltinDeserializationErrorKind::BadInetLength { got } => write!(
2527                f,
2528                "the length of read value in bytes ({got}) is not suitable for IP address; expected 4 or 16"
2529            ),
2530            BuiltinDeserializationErrorKind::SetOrListError(err) => err.fmt(f),
2531            BuiltinDeserializationErrorKind::VectorError(err) => err.fmt(f),
2532            BuiltinDeserializationErrorKind::MapError(err) => err.fmt(f),
2533            BuiltinDeserializationErrorKind::TupleError(err) => err.fmt(f),
2534            BuiltinDeserializationErrorKind::UdtError(err) => err.fmt(f),
2535            BuiltinDeserializationErrorKind::Unsupported => {
2536                f.write_str("deserialization of this CQL type is not supported by the driver")
2537            }
2538        }
2539    }
2540}
2541
2542/// Describes why deserialization of a set or list type failed.
2543#[derive(Debug, Clone)]
2544#[non_exhaustive]
2545pub enum SetOrListDeserializationErrorKind {
2546    /// Failed to deserialize set or list's length.
2547    LengthDeserializationFailed(DeserializationError),
2548
2549    /// One of the elements of the set/list failed to deserialize.
2550    ElementDeserializationFailed(DeserializationError),
2551}
2552
2553impl Display for SetOrListDeserializationErrorKind {
2554    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2555        match self {
2556            SetOrListDeserializationErrorKind::LengthDeserializationFailed(err) => {
2557                write!(f, "failed to deserialize set or list's length: {err}")
2558            }
2559            SetOrListDeserializationErrorKind::ElementDeserializationFailed(err) => {
2560                write!(f, "failed to deserialize one of the elements: {err}")
2561            }
2562        }
2563    }
2564}
2565
2566impl From<SetOrListDeserializationErrorKind> for BuiltinDeserializationErrorKind {
2567    #[inline]
2568    fn from(err: SetOrListDeserializationErrorKind) -> Self {
2569        Self::SetOrListError(err)
2570    }
2571}
2572
2573/// Describes why deserialization of a vector type failed.
2574#[derive(Error, Debug, Clone)]
2575#[non_exhaustive]
2576pub enum VectorDeserializationErrorKind {
2577    /// One of the elements of the vector failed to deserialize.
2578    #[error("failed to deserialize one of the elements: {0}")]
2579    ElementDeserializationFailed(DeserializationError),
2580}
2581
2582impl From<VectorDeserializationErrorKind> for BuiltinDeserializationErrorKind {
2583    #[inline]
2584    fn from(err: VectorDeserializationErrorKind) -> Self {
2585        Self::VectorError(err)
2586    }
2587}
2588
2589/// Describes why deserialization of a map type failed.
2590#[derive(Debug, Clone)]
2591#[non_exhaustive]
2592// Check triggers because all variants end with "DeserializationFailed".
2593// TODO(2.0): Remove the "DeserializationFailed" postfix from variants.
2594#[expect(clippy::enum_variant_names)]
2595pub enum MapDeserializationErrorKind {
2596    /// Failed to deserialize map's length.
2597    LengthDeserializationFailed(DeserializationError),
2598
2599    /// One of the keys in the map failed to deserialize.
2600    KeyDeserializationFailed(DeserializationError),
2601
2602    /// One of the values in the map failed to deserialize.
2603    ValueDeserializationFailed(DeserializationError),
2604}
2605
2606impl Display for MapDeserializationErrorKind {
2607    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2608        match self {
2609            MapDeserializationErrorKind::LengthDeserializationFailed(err) => {
2610                write!(f, "failed to deserialize map's length: {err}")
2611            }
2612            MapDeserializationErrorKind::KeyDeserializationFailed(err) => {
2613                write!(f, "failed to deserialize one of the keys: {err}")
2614            }
2615            MapDeserializationErrorKind::ValueDeserializationFailed(err) => {
2616                write!(f, "failed to deserialize one of the values: {err}")
2617            }
2618        }
2619    }
2620}
2621
2622impl From<MapDeserializationErrorKind> for BuiltinDeserializationErrorKind {
2623    fn from(err: MapDeserializationErrorKind) -> Self {
2624        Self::MapError(err)
2625    }
2626}
2627
2628/// Describes why deserialization of a tuple failed.
2629#[derive(Debug, Clone)]
2630#[non_exhaustive]
2631pub enum TupleDeserializationErrorKind {
2632    /// One of the tuple fields failed to deserialize.
2633    FieldDeserializationFailed {
2634        /// Index of the tuple field that failed to deserialize.
2635        position: usize,
2636
2637        /// The error that caused the tuple field deserialization to fail.
2638        err: DeserializationError,
2639    },
2640}
2641
2642impl Display for TupleDeserializationErrorKind {
2643    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2644        match self {
2645            TupleDeserializationErrorKind::FieldDeserializationFailed {
2646                position: index,
2647                err,
2648            } => {
2649                write!(f, "field no. {index} failed to deserialize: {err}")
2650            }
2651        }
2652    }
2653}
2654
2655impl From<TupleDeserializationErrorKind> for BuiltinDeserializationErrorKind {
2656    fn from(err: TupleDeserializationErrorKind) -> Self {
2657        Self::TupleError(err)
2658    }
2659}
2660
2661/// Describes why deserialization of a user defined type failed.
2662#[derive(Debug, Clone)]
2663#[non_exhaustive]
2664pub enum UdtDeserializationErrorKind {
2665    /// One of the fields failed to deserialize.
2666    FieldDeserializationFailed {
2667        /// Name of the field which failed to deserialize.
2668        field_name: String,
2669
2670        /// The error that caused the UDT field deserialization to fail.
2671        err: DeserializationError,
2672    },
2673}
2674
2675impl Display for UdtDeserializationErrorKind {
2676    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2677        match self {
2678            UdtDeserializationErrorKind::FieldDeserializationFailed { field_name, err } => {
2679                write!(f, "field {field_name} failed to deserialize: {err}")
2680            }
2681        }
2682    }
2683}
2684
2685impl From<UdtDeserializationErrorKind> for BuiltinDeserializationErrorKind {
2686    fn from(err: UdtDeserializationErrorKind) -> Self {
2687        Self::UdtError(err)
2688    }
2689}
2690
2691#[cfg(test)]
2692#[path = "value_tests.rs"]
2693pub(crate) mod tests;