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