Skip to main content

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