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