1use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
7use std::fmt::Display;
8use std::hash::BuildHasher;
9use std::net::IpAddr;
10use std::ops::Deref as _;
11use std::sync::Arc;
12
13use bytes::Bytes;
14use thiserror::Error;
15use uuid::Uuid;
16
17use crate::frame::response::result::{CollectionType, ColumnType, NativeType};
18use crate::frame::types::{unsigned_vint_encode, vint_encode};
19use crate::value::{
20 Counter, CqlDate, CqlDecimal, CqlDecimalBorrowed, CqlDuration, CqlTime, CqlTimestamp,
21 CqlTimeuuid, CqlValue, CqlVarint, CqlVarintBorrowed, MaybeUnset, Unset,
22};
23
24#[cfg(feature = "chrono-04")]
25use crate::value::ValueOverflow;
26
27use super::writers::WrittenCellProof;
28use super::{CellValueBuilder, CellWriter, SerializationError};
29
30pub trait SerializeValue {
37 fn serialize<'b>(
53 &self,
54 typ: &ColumnType,
55 writer: CellWriter<'b>,
56 ) -> Result<WrittenCellProof<'b>, SerializationError>;
57}
58
59macro_rules! exact_type_check {
60 ($typ:ident, $($cql:tt),*) => {
61 match $typ {
62 $(ColumnType::Native(NativeType::$cql))|* => {},
63 _ => return Err(mk_typck_err::<Self>(
64 $typ,
65 BuiltinTypeCheckErrorKind::MismatchedType {
66 expected: &[$(ColumnType::Native(NativeType::$cql)),*],
67 }
68 ))
69 }
70 };
71}
72
73macro_rules! impl_serialize_via_writer {
74 (|$me:ident, $writer:ident| $e:expr) => {
75 impl_serialize_via_writer!(|$me, _typ, $writer| $e);
76 };
77 (|$me:ident, $typ:ident, $writer:ident| $e:expr) => {
78 fn serialize<'b>(
79 &self,
80 typ: &ColumnType,
81 writer: CellWriter<'b>,
82 ) -> Result<WrittenCellProof<'b>, SerializationError> {
83 let $writer = writer;
84 let $typ = typ;
85 let $me = self;
86 let proof = $e;
87 Ok(proof)
88 }
89 };
90}
91
92impl SerializeValue for i8 {
93 impl_serialize_via_writer!(|me, typ, writer| {
94 exact_type_check!(typ, TinyInt);
95 writer.set_value(me.to_be_bytes().as_slice()).unwrap()
96 });
97}
98impl SerializeValue for i16 {
99 impl_serialize_via_writer!(|me, typ, writer| {
100 exact_type_check!(typ, SmallInt);
101 writer.set_value(me.to_be_bytes().as_slice()).unwrap()
102 });
103}
104impl SerializeValue for i32 {
105 impl_serialize_via_writer!(|me, typ, writer| {
106 exact_type_check!(typ, Int);
107 writer.set_value(me.to_be_bytes().as_slice()).unwrap()
108 });
109}
110impl SerializeValue for i64 {
111 impl_serialize_via_writer!(|me, typ, writer| {
112 exact_type_check!(typ, BigInt);
113 writer.set_value(me.to_be_bytes().as_slice()).unwrap()
114 });
115}
116impl SerializeValue for CqlDecimal {
117 impl_serialize_via_writer!(|me, typ, writer| {
118 exact_type_check!(typ, Decimal);
119 let mut builder = writer.into_value_builder();
120 let (bytes, scale) = me.as_signed_be_bytes_slice_and_exponent();
121 builder.append_bytes(&scale.to_be_bytes());
122 builder.append_bytes(bytes);
123 builder
124 .finish()
125 .map_err(|_| mk_ser_err::<Self>(typ, BuiltinSerializationErrorKind::SizeOverflow))?
126 });
127}
128impl SerializeValue for CqlDecimalBorrowed<'_> {
129 impl_serialize_via_writer!(|me, typ, writer| {
130 exact_type_check!(typ, Decimal);
131 let mut builder = writer.into_value_builder();
132 let (bytes, scale) = me.as_signed_be_bytes_slice_and_exponent();
133 builder.append_bytes(&scale.to_be_bytes());
134 builder.append_bytes(bytes);
135 builder
136 .finish()
137 .map_err(|_| mk_ser_err::<Self>(typ, BuiltinSerializationErrorKind::SizeOverflow))?
138 });
139}
140#[cfg(feature = "bigdecimal-04")]
141impl SerializeValue for bigdecimal_04::BigDecimal {
142 impl_serialize_via_writer!(|me, typ, writer| {
143 exact_type_check!(typ, Decimal);
144 let mut builder = writer.into_value_builder();
145 let (value, scale) = me.as_bigint_and_exponent();
146 let scale: i32 = scale
147 .try_into()
148 .map_err(|_| mk_ser_err::<Self>(typ, BuiltinSerializationErrorKind::ValueOverflow))?;
149 builder.append_bytes(&scale.to_be_bytes());
150 builder.append_bytes(&value.to_signed_bytes_be());
151 builder
152 .finish()
153 .map_err(|_| mk_ser_err::<Self>(typ, BuiltinSerializationErrorKind::SizeOverflow))?
154 });
155}
156impl SerializeValue for CqlDate {
157 impl_serialize_via_writer!(|me, typ, writer| {
158 exact_type_check!(typ, Date);
159 writer.set_value(me.0.to_be_bytes().as_slice()).unwrap()
160 });
161}
162impl SerializeValue for CqlTimestamp {
163 impl_serialize_via_writer!(|me, typ, writer| {
164 exact_type_check!(typ, Timestamp);
165 writer.set_value(me.0.to_be_bytes().as_slice()).unwrap()
166 });
167}
168impl SerializeValue for CqlTime {
169 impl_serialize_via_writer!(|me, typ, writer| {
170 exact_type_check!(typ, Time);
171 writer.set_value(me.0.to_be_bytes().as_slice()).unwrap()
172 });
173}
174#[cfg(feature = "chrono-04")]
175impl SerializeValue for chrono_04::NaiveDate {
176 impl_serialize_via_writer!(|me, typ, writer| {
177 exact_type_check!(typ, Date);
178 <CqlDate as SerializeValue>::serialize(&(*me).into(), typ, writer)?
179 });
180}
181#[cfg(feature = "chrono-04")]
182impl SerializeValue for chrono_04::DateTime<chrono_04::Utc> {
183 impl_serialize_via_writer!(|me, typ, writer| {
184 exact_type_check!(typ, Timestamp);
185 <CqlTimestamp as SerializeValue>::serialize(&(*me).into(), typ, writer)?
186 });
187}
188#[cfg(feature = "chrono-04")]
189impl SerializeValue for chrono_04::NaiveTime {
190 impl_serialize_via_writer!(|me, typ, writer| {
191 exact_type_check!(typ, Time);
192 let cql_time = CqlTime::try_from(*me).map_err(|_: ValueOverflow| {
193 mk_ser_err::<Self>(typ, BuiltinSerializationErrorKind::ValueOverflow)
194 })?;
195 <CqlTime as SerializeValue>::serialize(&cql_time, typ, writer)?
196 });
197}
198#[cfg(feature = "time-03")]
199impl SerializeValue for time_03::Date {
200 impl_serialize_via_writer!(|me, typ, writer| {
201 exact_type_check!(typ, Date);
202 <CqlDate as SerializeValue>::serialize(&(*me).into(), typ, writer)?
203 });
204}
205#[cfg(feature = "time-03")]
206impl SerializeValue for time_03::OffsetDateTime {
207 impl_serialize_via_writer!(|me, typ, writer| {
208 exact_type_check!(typ, Timestamp);
209 <CqlTimestamp as SerializeValue>::serialize(&(*me).into(), typ, writer)?
210 });
211}
212#[cfg(feature = "time-03")]
213impl SerializeValue for time_03::Time {
214 impl_serialize_via_writer!(|me, typ, writer| {
215 exact_type_check!(typ, Time);
216 <CqlTime as SerializeValue>::serialize(&(*me).into(), typ, writer)?
217 });
218}
219#[cfg(feature = "secrecy-08")]
220impl<V: SerializeValue + secrecy_08::Zeroize> SerializeValue for secrecy_08::Secret<V> {
221 fn serialize<'b>(
222 &self,
223 typ: &ColumnType,
224 writer: CellWriter<'b>,
225 ) -> Result<WrittenCellProof<'b>, SerializationError> {
226 use secrecy_08::ExposeSecret;
227 V::serialize(self.expose_secret(), typ, writer).map_err(fix_rust_name_in_err::<Self>)
228 }
229}
230impl SerializeValue for bool {
231 impl_serialize_via_writer!(|me, typ, writer| {
232 exact_type_check!(typ, Boolean);
233 writer.set_value(&[*me as u8]).unwrap()
234 });
235}
236impl SerializeValue for f32 {
237 impl_serialize_via_writer!(|me, typ, writer| {
238 exact_type_check!(typ, Float);
239 writer.set_value(me.to_be_bytes().as_slice()).unwrap()
240 });
241}
242impl SerializeValue for f64 {
243 impl_serialize_via_writer!(|me, typ, writer| {
244 exact_type_check!(typ, Double);
245 writer.set_value(me.to_be_bytes().as_slice()).unwrap()
246 });
247}
248impl SerializeValue for Uuid {
249 impl_serialize_via_writer!(|me, typ, writer| {
250 exact_type_check!(typ, Uuid);
251 writer.set_value(me.as_bytes().as_ref()).unwrap()
252 });
253}
254impl SerializeValue for CqlTimeuuid {
255 impl_serialize_via_writer!(|me, typ, writer| {
256 exact_type_check!(typ, Timeuuid);
257 writer.set_value(me.as_bytes().as_ref()).unwrap()
258 });
259}
260impl SerializeValue for CqlVarint {
261 impl_serialize_via_writer!(|me, typ, writer| {
262 exact_type_check!(typ, Varint);
263 writer
264 .set_value(me.as_signed_bytes_be_slice())
265 .map_err(|_| mk_ser_err::<Self>(typ, BuiltinSerializationErrorKind::SizeOverflow))?
266 });
267}
268impl SerializeValue for CqlVarintBorrowed<'_> {
269 impl_serialize_via_writer!(|me, typ, writer| {
270 exact_type_check!(typ, Varint);
271 writer
272 .set_value(me.as_signed_bytes_be_slice())
273 .map_err(|_| mk_ser_err::<Self>(typ, BuiltinSerializationErrorKind::SizeOverflow))?
274 });
275}
276#[cfg(feature = "num-bigint-03")]
277impl SerializeValue for num_bigint_03::BigInt {
278 impl_serialize_via_writer!(|me, typ, writer| {
279 exact_type_check!(typ, Varint);
280 writer
284 .set_value(me.to_signed_bytes_be().as_slice())
285 .map_err(|_| mk_ser_err::<Self>(typ, BuiltinSerializationErrorKind::SizeOverflow))?
286 });
287}
288#[cfg(feature = "num-bigint-04")]
289impl SerializeValue for num_bigint_04::BigInt {
290 impl_serialize_via_writer!(|me, typ, writer| {
291 exact_type_check!(typ, Varint);
292 writer
294 .set_value(me.to_signed_bytes_be().as_slice())
295 .map_err(|_| mk_ser_err::<Self>(typ, BuiltinSerializationErrorKind::SizeOverflow))?
296 });
297}
298impl SerializeValue for str {
299 impl_serialize_via_writer!(|me, typ, writer| {
300 exact_type_check!(typ, Ascii, Text);
301 writer
302 .set_value(me.as_bytes())
303 .map_err(|_| mk_ser_err::<Self>(typ, BuiltinSerializationErrorKind::SizeOverflow))?
304 });
305}
306impl SerializeValue for Vec<u8> {
307 impl_serialize_via_writer!(|me, typ, writer| {
308 exact_type_check!(typ, Blob);
309 writer
310 .set_value(me.as_ref())
311 .map_err(|_| mk_ser_err::<Self>(typ, BuiltinSerializationErrorKind::SizeOverflow))?
312 });
313}
314impl SerializeValue for &[u8] {
315 impl_serialize_via_writer!(|me, typ, writer| {
316 exact_type_check!(typ, Blob);
317 writer
318 .set_value(me)
319 .map_err(|_| mk_ser_err::<Self>(typ, BuiltinSerializationErrorKind::SizeOverflow))?
320 });
321}
322impl<const N: usize> SerializeValue for [u8; N] {
323 impl_serialize_via_writer!(|me, typ, writer| {
324 exact_type_check!(typ, Blob);
325 writer
326 .set_value(me.as_ref())
327 .map_err(|_| mk_ser_err::<Self>(typ, BuiltinSerializationErrorKind::SizeOverflow))?
328 });
329}
330impl SerializeValue for Bytes {
331 impl_serialize_via_writer!(|me, typ, writer| {
332 exact_type_check!(typ, Blob);
333 writer
334 .set_value(me)
335 .map_err(|_| mk_ser_err::<Self>(typ, BuiltinSerializationErrorKind::SizeOverflow))?
336 });
337}
338impl SerializeValue for IpAddr {
339 impl_serialize_via_writer!(|me, typ, writer| {
340 exact_type_check!(typ, Inet);
341 match me {
342 IpAddr::V4(ip) => writer.set_value(&ip.octets()).unwrap(),
343 IpAddr::V6(ip) => writer.set_value(&ip.octets()).unwrap(),
344 }
345 });
346}
347impl SerializeValue for String {
348 impl_serialize_via_writer!(|me, typ, writer| {
349 exact_type_check!(typ, Ascii, Text);
350 writer
351 .set_value(me.as_bytes())
352 .map_err(|_| mk_ser_err::<Self>(typ, BuiltinSerializationErrorKind::SizeOverflow))?
353 });
354}
355impl<T: SerializeValue> SerializeValue for Option<T> {
356 fn serialize<'b>(
357 &self,
358 typ: &ColumnType,
359 writer: CellWriter<'b>,
360 ) -> Result<WrittenCellProof<'b>, SerializationError> {
361 match self {
362 Some(v) => v
363 .serialize(typ, writer)
364 .map_err(fix_rust_name_in_err::<Self>),
365 None => Ok(writer.set_null()),
366 }
367 }
368}
369impl SerializeValue for Unset {
370 impl_serialize_via_writer!(|_me, writer| writer.set_unset());
371}
372impl SerializeValue for Counter {
373 impl_serialize_via_writer!(|me, typ, writer| {
374 exact_type_check!(typ, Counter);
375 writer.set_value(me.0.to_be_bytes().as_slice()).unwrap()
376 });
377}
378impl SerializeValue for CqlDuration {
379 impl_serialize_via_writer!(|me, typ, writer| {
380 exact_type_check!(typ, Duration);
381 let mut buf = Vec::with_capacity(27); vint_encode(me.months as i64, &mut buf);
384 vint_encode(me.days as i64, &mut buf);
385 vint_encode(me.nanoseconds, &mut buf);
386 writer.set_value(buf.as_slice()).unwrap()
387 });
388}
389impl<V: SerializeValue> SerializeValue for MaybeUnset<V> {
390 fn serialize<'b>(
391 &self,
392 typ: &ColumnType,
393 writer: CellWriter<'b>,
394 ) -> Result<WrittenCellProof<'b>, SerializationError> {
395 match self {
396 MaybeUnset::Set(v) => v
397 .serialize(typ, writer)
398 .map_err(fix_rust_name_in_err::<Self>),
399 MaybeUnset::Unset => Ok(writer.set_unset()),
400 }
401 }
402}
403impl<T: SerializeValue + ?Sized> SerializeValue for &T {
404 fn serialize<'b>(
405 &self,
406 typ: &ColumnType,
407 writer: CellWriter<'b>,
408 ) -> Result<WrittenCellProof<'b>, SerializationError> {
409 T::serialize(*self, typ, writer).map_err(fix_rust_name_in_err::<Self>)
410 }
411}
412impl<T: SerializeValue + ?Sized> SerializeValue for Box<T> {
413 fn serialize<'b>(
414 &self,
415 typ: &ColumnType,
416 writer: CellWriter<'b>,
417 ) -> Result<WrittenCellProof<'b>, SerializationError> {
418 T::serialize(&**self, typ, writer).map_err(fix_rust_name_in_err::<Self>)
419 }
420}
421impl<T: SerializeValue + ?Sized> SerializeValue for Arc<T> {
422 fn serialize<'b>(
423 &self,
424 typ: &ColumnType,
425 writer: CellWriter<'b>,
426 ) -> Result<WrittenCellProof<'b>, SerializationError> {
427 T::serialize(&**self, typ, writer).map_err(fix_rust_name_in_err::<Self>)
428 }
429}
430impl<V: SerializeValue, S: BuildHasher + Default> SerializeValue for HashSet<V, S> {
431 fn serialize<'b>(
432 &self,
433 typ: &ColumnType,
434 writer: CellWriter<'b>,
435 ) -> Result<WrittenCellProof<'b>, SerializationError> {
436 serialize_sequence(
437 std::any::type_name::<Self>(),
438 self.len(),
439 self.iter(),
440 typ,
441 writer,
442 )
443 }
444}
445impl<K: SerializeValue, V: SerializeValue, S: BuildHasher> SerializeValue for HashMap<K, V, S> {
446 fn serialize<'b>(
447 &self,
448 typ: &ColumnType,
449 writer: CellWriter<'b>,
450 ) -> Result<WrittenCellProof<'b>, SerializationError> {
451 serialize_mapping(
452 std::any::type_name::<Self>(),
453 self.len(),
454 self.iter(),
455 typ,
456 writer,
457 )
458 }
459}
460impl<V: SerializeValue> SerializeValue for BTreeSet<V> {
461 fn serialize<'b>(
462 &self,
463 typ: &ColumnType,
464 writer: CellWriter<'b>,
465 ) -> Result<WrittenCellProof<'b>, SerializationError> {
466 serialize_sequence(
467 std::any::type_name::<Self>(),
468 self.len(),
469 self.iter(),
470 typ,
471 writer,
472 )
473 }
474}
475impl<K: SerializeValue, V: SerializeValue> SerializeValue for BTreeMap<K, V> {
476 fn serialize<'b>(
477 &self,
478 typ: &ColumnType,
479 writer: CellWriter<'b>,
480 ) -> Result<WrittenCellProof<'b>, SerializationError> {
481 serialize_mapping(
482 std::any::type_name::<Self>(),
483 self.len(),
484 self.iter(),
485 typ,
486 writer,
487 )
488 }
489}
490impl<T: SerializeValue> SerializeValue for Vec<T> {
491 fn serialize<'b>(
492 &self,
493 typ: &ColumnType,
494 writer: CellWriter<'b>,
495 ) -> Result<WrittenCellProof<'b>, SerializationError> {
496 match typ {
497 ColumnType::Collection {
498 typ: CollectionType::List(_) | CollectionType::Set(_),
499 ..
500 } => serialize_sequence(
501 std::any::type_name::<Self>(),
502 self.len(),
503 self.iter(),
504 typ,
505 writer,
506 ),
507
508 ColumnType::Vector {
509 typ: element_type,
510 dimensions,
511 } => serialize_vector(
512 std::any::type_name::<Self>(),
513 self.len(),
514 self.iter(),
515 element_type,
516 *dimensions,
517 typ,
518 writer,
519 ),
520
521 _ => Err(mk_typck_err_named(
522 std::any::type_name::<Self>(),
523 typ,
524 SetOrListTypeCheckErrorKind::NotSetOrList,
525 )),
526 }
527 }
528}
529impl<'a, T: SerializeValue + 'a> SerializeValue for &'a [T] {
530 fn serialize<'b>(
531 &self,
532 typ: &ColumnType,
533 writer: CellWriter<'b>,
534 ) -> Result<WrittenCellProof<'b>, SerializationError> {
535 match typ {
536 ColumnType::Collection {
537 typ: CollectionType::List(_) | CollectionType::Set(_),
538 ..
539 } => serialize_sequence(
540 std::any::type_name::<Self>(),
541 self.len(),
542 self.iter(),
543 typ,
544 writer,
545 ),
546
547 ColumnType::Vector {
548 typ: element_type,
549 dimensions,
550 } => serialize_vector(
551 std::any::type_name::<Self>(),
552 self.len(),
553 self.iter(),
554 element_type,
555 *dimensions,
556 typ,
557 writer,
558 ),
559
560 _ => Err(mk_typck_err_named(
561 std::any::type_name::<Self>(),
562 typ,
563 SetOrListTypeCheckErrorKind::NotSetOrList,
564 )),
565 }
566 }
567}
568impl SerializeValue for CqlValue {
569 fn serialize<'b>(
570 &self,
571 typ: &ColumnType,
572 writer: CellWriter<'b>,
573 ) -> Result<WrittenCellProof<'b>, SerializationError> {
574 serialize_cql_value(self, typ, writer).map_err(fix_rust_name_in_err::<Self>)
575 }
576}
577
578fn serialize_cql_value<'b>(
579 value: &CqlValue,
580 typ: &ColumnType,
581 writer: CellWriter<'b>,
582) -> Result<WrittenCellProof<'b>, SerializationError> {
583 match value {
584 CqlValue::Ascii(a) => <_ as SerializeValue>::serialize(&a, typ, writer),
585 CqlValue::Boolean(b) => <_ as SerializeValue>::serialize(&b, typ, writer),
586 CqlValue::Blob(b) => <_ as SerializeValue>::serialize(&b, typ, writer),
587 CqlValue::Counter(c) => <_ as SerializeValue>::serialize(&c, typ, writer),
588 CqlValue::Decimal(d) => <_ as SerializeValue>::serialize(&d, typ, writer),
589 CqlValue::Date(d) => <_ as SerializeValue>::serialize(&d, typ, writer),
590 CqlValue::Double(d) => <_ as SerializeValue>::serialize(&d, typ, writer),
591 CqlValue::Duration(d) => <_ as SerializeValue>::serialize(&d, typ, writer),
592 CqlValue::Empty => {
593 if !typ.supports_special_empty_value() {
594 return Err(mk_typck_err::<CqlValue>(
595 typ,
596 BuiltinTypeCheckErrorKind::NotEmptyable,
597 ));
598 }
599 Ok(writer.set_value(&[]).unwrap())
600 }
601 CqlValue::Float(f) => <_ as SerializeValue>::serialize(&f, typ, writer),
602 CqlValue::Int(i) => <_ as SerializeValue>::serialize(&i, typ, writer),
603 CqlValue::BigInt(b) => <_ as SerializeValue>::serialize(&b, typ, writer),
604 CqlValue::Text(t) => <_ as SerializeValue>::serialize(&t, typ, writer),
605 CqlValue::Timestamp(t) => <_ as SerializeValue>::serialize(&t, typ, writer),
606 CqlValue::Inet(i) => <_ as SerializeValue>::serialize(&i, typ, writer),
607 CqlValue::List(l) => <_ as SerializeValue>::serialize(&l, typ, writer),
608 CqlValue::Map(m) => serialize_mapping(
609 std::any::type_name::<CqlValue>(),
610 m.len(),
611 m.iter().map(|p| (&p.0, &p.1)),
612 typ,
613 writer,
614 ),
615 CqlValue::Set(s) => <_ as SerializeValue>::serialize(&s, typ, writer),
616 CqlValue::UserDefinedType {
617 keyspace,
618 name: type_name,
619 fields,
620 } => serialize_udt(typ, keyspace, type_name, fields, writer),
621 CqlValue::SmallInt(s) => <_ as SerializeValue>::serialize(&s, typ, writer),
622 CqlValue::TinyInt(t) => <_ as SerializeValue>::serialize(&t, typ, writer),
623 CqlValue::Time(t) => <_ as SerializeValue>::serialize(&t, typ, writer),
624 CqlValue::Timeuuid(t) => <_ as SerializeValue>::serialize(&t, typ, writer),
625 CqlValue::Tuple(t) => {
626 let fields = match typ {
629 ColumnType::Tuple(fields) => {
630 if fields.len() < t.len() {
631 return Err(mk_typck_err::<CqlValue>(
632 typ,
633 TupleTypeCheckErrorKind::WrongElementCount {
634 rust_type_el_count: t.len(),
635 cql_type_el_count: fields.len(),
636 },
637 ));
638 }
639 fields
640 }
641 _ => {
642 return Err(mk_typck_err::<CqlValue>(
643 typ,
644 TupleTypeCheckErrorKind::NotTuple,
645 ))
646 }
647 };
648 serialize_tuple_like(typ, fields.iter(), t.iter(), writer)
649 }
650 CqlValue::Uuid(u) => <_ as SerializeValue>::serialize(&u, typ, writer),
651 CqlValue::Varint(v) => <_ as SerializeValue>::serialize(&v, typ, writer),
652 CqlValue::Vector(v) => <_ as SerializeValue>::serialize(&v, typ, writer),
653 }
654}
655
656fn fix_rust_name_in_err<RustT>(mut err: SerializationError) -> SerializationError {
657 let rust_name = std::any::type_name::<RustT>();
663
664 match Arc::get_mut(&mut err.0) {
665 Some(err_mut) => {
666 if let Some(err) = err_mut.downcast_mut::<BuiltinTypeCheckError>() {
667 err.rust_name = rust_name;
668 } else if let Some(err) = err_mut.downcast_mut::<BuiltinSerializationError>() {
669 err.rust_name = rust_name;
670 }
671 }
672 None => {
673 if let Some(err) = err.0.downcast_ref::<BuiltinTypeCheckError>() {
677 if err.rust_name != rust_name {
678 return SerializationError::new(BuiltinTypeCheckError {
679 rust_name,
680 ..err.clone()
681 });
682 }
683 }
684 if let Some(err) = err.0.downcast_ref::<BuiltinSerializationError>() {
685 if err.rust_name != rust_name {
686 return SerializationError::new(BuiltinSerializationError {
687 rust_name,
688 ..err.clone()
689 });
690 }
691 }
692 }
693 };
694
695 err
696}
697
698fn serialize_udt<'b>(
699 typ: &ColumnType,
700 keyspace: &str,
701 type_name: &str,
702 values: &[(String, Option<CqlValue>)],
703 writer: CellWriter<'b>,
704) -> Result<WrittenCellProof<'b>, SerializationError> {
705 let (dst_type_name, dst_keyspace, field_types) = match typ {
706 ColumnType::UserDefinedType {
707 definition: udt, ..
708 } => (&udt.name, &udt.keyspace, &udt.field_types),
709 _ => return Err(mk_typck_err::<CqlValue>(typ, UdtTypeCheckErrorKind::NotUdt)),
710 };
711
712 if keyspace != dst_keyspace || type_name != dst_type_name {
713 return Err(mk_typck_err::<CqlValue>(
714 typ,
715 UdtTypeCheckErrorKind::NameMismatch {
716 keyspace: dst_keyspace.clone().into_owned(),
717 type_name: dst_type_name.clone().into_owned(),
718 },
719 ));
720 }
721
722 let mut indexed_fields: HashMap<_, _> = values.iter().map(|(k, v)| (k.as_str(), v)).collect();
725
726 let mut builder = writer.into_value_builder();
727 for (fname, ftyp) in field_types {
728 let fvalue = indexed_fields
731 .remove(fname.deref())
732 .and_then(|x| x.as_ref());
733
734 let writer = builder.make_sub_writer();
735 match fvalue {
736 None => writer.set_null(),
737 Some(v) => serialize_cql_value(v, ftyp, writer).map_err(|err| {
738 let err = fix_rust_name_in_err::<CqlValue>(err);
739 mk_ser_err::<CqlValue>(
740 typ,
741 UdtSerializationErrorKind::FieldSerializationFailed {
742 field_name: fname.clone().into_owned(),
743 err,
744 },
745 )
746 })?,
747 };
748 }
749
750 if !indexed_fields.is_empty() {
752 let fname = indexed_fields.keys().min().unwrap();
755 return Err(mk_typck_err::<CqlValue>(
756 typ,
757 UdtTypeCheckErrorKind::NoSuchFieldInUdt {
758 field_name: fname.to_string(),
759 },
760 ));
761 }
762
763 builder
764 .finish()
765 .map_err(|_| mk_ser_err::<CqlValue>(typ, BuiltinSerializationErrorKind::SizeOverflow))
766}
767
768fn serialize_tuple_like<'t, 'b>(
769 typ: &ColumnType,
770 field_types: impl Iterator<Item = &'t ColumnType<'t>>,
771 field_values: impl Iterator<Item = &'t Option<CqlValue>>,
772 writer: CellWriter<'b>,
773) -> Result<WrittenCellProof<'b>, SerializationError> {
774 let mut builder = writer.into_value_builder();
775
776 for (index, (el, el_typ)) in field_values.zip(field_types).enumerate() {
777 let sub = builder.make_sub_writer();
778 match el {
779 None => sub.set_null(),
780 Some(el) => serialize_cql_value(el, el_typ, sub).map_err(|err| {
781 let err = fix_rust_name_in_err::<CqlValue>(err);
782 mk_ser_err::<CqlValue>(
783 typ,
784 TupleSerializationErrorKind::ElementSerializationFailed { index, err },
785 )
786 })?,
787 };
788 }
789
790 builder
791 .finish()
792 .map_err(|_| mk_ser_err::<CqlValue>(typ, BuiltinSerializationErrorKind::SizeOverflow))
793}
794
795macro_rules! impl_tuple {
796 (
797 $($typs:ident),*;
798 $($fidents:ident),*;
799 $($tidents:ident),*;
800 $length:expr
801 ) => {
802 impl<$($typs: SerializeValue),*> SerializeValue for ($($typs,)*) {
803 fn serialize<'b>(
804 &self,
805 typ: &ColumnType,
806 writer: CellWriter<'b>,
807 ) -> Result<WrittenCellProof<'b>, SerializationError> {
808 let ($($tidents,)*) = match typ {
809 ColumnType::Tuple(typs) => match typs.as_slice() {
810 [$($tidents),*] => ($($tidents,)*),
811 _ => return Err(mk_typck_err::<Self>(
812 typ,
813 TupleTypeCheckErrorKind::WrongElementCount {
814 rust_type_el_count: $length,
815 cql_type_el_count: typs.len(),
816 }
817 ))
818 }
819 _ => return Err(mk_typck_err::<Self>(
820 typ,
821 TupleTypeCheckErrorKind::NotTuple,
822 ))
823 };
824 let ($($fidents,)*) = self;
825 let mut builder = writer.into_value_builder();
826 let index = 0;
827 $(
828 <$typs as SerializeValue>::serialize($fidents, $tidents, builder.make_sub_writer())
829 .map_err(|err| mk_ser_err::<Self>(
830 typ,
831 TupleSerializationErrorKind::ElementSerializationFailed {
832 index,
833 err,
834 }
835 ))?;
836 let index = index + 1;
837 )*
838 let _ = index;
839 builder
840 .finish()
841 .map_err(|_| mk_ser_err::<Self>(typ, BuiltinSerializationErrorKind::SizeOverflow))
842 }
843 }
844 };
845}
846
847macro_rules! impl_tuples {
848 (;;;$length:expr) => {};
849 (
850 $typ:ident$(, $($typs:ident),*)?;
851 $fident:ident$(, $($fidents:ident),*)?;
852 $tident:ident$(, $($tidents:ident),*)?;
853 $length:expr
854 ) => {
855 impl_tuples!(
856 $($($typs),*)?;
857 $($($fidents),*)?;
858 $($($tidents),*)?;
859 $length - 1
860 );
861 impl_tuple!(
862 $typ$(, $($typs),*)?;
863 $fident$(, $($fidents),*)?;
864 $tident$(, $($tidents),*)?;
865 $length
866 );
867 };
868}
869
870impl_tuples!(
871 T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15;
872 f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15;
873 t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15;
874 16
875);
876
877fn serialize_sequence<'t, 'b, T: SerializeValue + 't>(
878 rust_name: &'static str,
879 len: usize,
880 iter: impl Iterator<Item = &'t T>,
881 typ: &ColumnType,
882 writer: CellWriter<'b>,
883) -> Result<WrittenCellProof<'b>, SerializationError> {
884 let elt = match typ {
885 ColumnType::Collection {
886 frozen: false,
887 typ: CollectionType::List(elt),
888 }
889 | ColumnType::Collection {
890 frozen: false,
891 typ: CollectionType::Set(elt),
892 } => elt,
893 _ => {
894 return Err(mk_typck_err_named(
895 rust_name,
896 typ,
897 SetOrListTypeCheckErrorKind::NotSetOrList,
898 ));
899 }
900 };
901
902 let mut builder = writer.into_value_builder();
903
904 let element_count: i32 = len.try_into().map_err(|_| {
905 mk_ser_err_named(
906 rust_name,
907 typ,
908 SetOrListSerializationErrorKind::TooManyElements,
909 )
910 })?;
911 builder.append_bytes(&element_count.to_be_bytes());
912
913 for el in iter {
914 T::serialize(el, elt, builder.make_sub_writer()).map_err(|err| {
915 mk_ser_err_named(
916 rust_name,
917 typ,
918 SetOrListSerializationErrorKind::ElementSerializationFailed(err),
919 )
920 })?;
921 }
922
923 builder
924 .finish()
925 .map_err(|_| mk_ser_err_named(rust_name, typ, BuiltinSerializationErrorKind::SizeOverflow))
926}
927
928fn serialize_next_constant_length_elem<'t, T: SerializeValue + 't>(
929 rust_name: &'static str,
930 element_type: &ColumnType,
931 typ: &ColumnType,
932 builder: &mut CellValueBuilder,
933 element: &'t T,
934) -> Result<(), SerializationError> {
935 T::serialize(
936 element,
937 element_type,
938 builder.make_sub_writer_without_size(),
939 )
940 .map_err(|err| {
941 mk_ser_err_named(
942 rust_name,
943 typ,
944 VectorSerializationErrorKind::ElementSerializationFailed(err),
945 )
946 })?;
947 Ok(())
948}
949
950fn serialize_next_variable_length_elem<'t, T: SerializeValue + 't>(
951 rust_name: &'static str,
952 element_type: &ColumnType,
953 typ: &ColumnType,
954 builder: &mut CellValueBuilder,
955 element: &'t T,
956) -> Result<(), SerializationError> {
957 let mut element_buffer = Vec::new();
958 let inner_writer = CellWriter::new_without_size(&mut element_buffer);
959 T::serialize(element, element_type, inner_writer).map_err(|err| {
960 mk_ser_err_named(
961 rust_name,
962 typ,
963 VectorSerializationErrorKind::ElementSerializationFailed(err),
964 )
965 })?;
966 let mut element_length_buffer = Vec::new();
967 unsigned_vint_encode(
968 element_buffer.len().try_into().unwrap(),
969 &mut element_length_buffer,
970 );
971 builder.append_bytes(element_length_buffer.as_slice());
972 builder.append_bytes(element_buffer.as_slice());
973 Ok(())
974}
975
976fn serialize_vector<'t, 'b, T: SerializeValue + 't>(
977 rust_name: &'static str,
978 len: usize,
979 iter: impl Iterator<Item = &'t T>,
980 element_type: &ColumnType,
981 dimensions: u16,
982 typ: &ColumnType,
983 writer: CellWriter<'b>,
984) -> Result<WrittenCellProof<'b>, SerializationError> {
985 if len != dimensions as usize {
986 return Err(mk_ser_err_named(
987 rust_name,
988 typ,
989 VectorSerializationErrorKind::InvalidNumberOfElements(len, dimensions),
990 ));
991 }
992 let mut builder = writer.into_value_builder();
993 match element_type.type_size() {
994 Some(_) => {
995 for element in iter {
996 serialize_next_constant_length_elem(
997 rust_name,
998 element_type,
999 typ,
1000 &mut builder,
1001 element,
1002 )?;
1003 }
1004 }
1005 None => {
1006 for element in iter {
1007 serialize_next_variable_length_elem(
1008 rust_name,
1009 element_type,
1010 typ,
1011 &mut builder,
1012 element,
1013 )?;
1014 }
1015 }
1016 }
1017
1018 builder
1019 .finish()
1020 .map_err(|_| mk_ser_err_named(rust_name, typ, BuiltinSerializationErrorKind::SizeOverflow))
1021}
1022
1023fn serialize_mapping<'t, 'b, K: SerializeValue + 't, V: SerializeValue + 't>(
1024 rust_name: &'static str,
1025 len: usize,
1026 iter: impl Iterator<Item = (&'t K, &'t V)>,
1027 typ: &ColumnType,
1028 writer: CellWriter<'b>,
1029) -> Result<WrittenCellProof<'b>, SerializationError> {
1030 let (ktyp, vtyp) = match typ {
1031 ColumnType::Collection {
1032 frozen: false,
1033 typ: CollectionType::Map(k, v),
1034 } => (k, v),
1035 _ => {
1036 return Err(mk_typck_err_named(
1037 rust_name,
1038 typ,
1039 MapTypeCheckErrorKind::NotMap,
1040 ));
1041 }
1042 };
1043
1044 let mut builder = writer.into_value_builder();
1045
1046 let element_count: i32 = len.try_into().map_err(|_| {
1047 mk_ser_err_named(rust_name, typ, MapSerializationErrorKind::TooManyElements)
1048 })?;
1049 builder.append_bytes(&element_count.to_be_bytes());
1050
1051 for (k, v) in iter {
1052 K::serialize(k, ktyp, builder.make_sub_writer()).map_err(|err| {
1053 mk_ser_err_named(
1054 rust_name,
1055 typ,
1056 MapSerializationErrorKind::KeySerializationFailed(err),
1057 )
1058 })?;
1059 V::serialize(v, vtyp, builder.make_sub_writer()).map_err(|err| {
1060 mk_ser_err_named(
1061 rust_name,
1062 typ,
1063 MapSerializationErrorKind::ValueSerializationFailed(err),
1064 )
1065 })?;
1066 }
1067
1068 builder
1069 .finish()
1070 .map_err(|_| mk_ser_err_named(rust_name, typ, BuiltinSerializationErrorKind::SizeOverflow))
1071}
1072
1073#[derive(Debug, Error, Clone)]
1075#[error("Failed to type check Rust type {rust_name} against CQL type {got:?}: {kind}")]
1076pub struct BuiltinTypeCheckError {
1077 pub rust_name: &'static str,
1079
1080 pub got: ColumnType<'static>,
1082
1083 pub kind: BuiltinTypeCheckErrorKind,
1085}
1086
1087fn mk_typck_err<T: ?Sized>(
1088 got: &ColumnType,
1089 kind: impl Into<BuiltinTypeCheckErrorKind>,
1090) -> SerializationError {
1091 mk_typck_err_named(std::any::type_name::<T>(), got, kind)
1092}
1093
1094fn mk_typck_err_named(
1095 name: &'static str,
1096 got: &ColumnType,
1097 kind: impl Into<BuiltinTypeCheckErrorKind>,
1098) -> SerializationError {
1099 SerializationError::new(BuiltinTypeCheckError {
1100 rust_name: name,
1101 got: got.clone().into_owned(),
1102 kind: kind.into(),
1103 })
1104}
1105
1106#[derive(Debug, Error, Clone)]
1108#[error("Failed to serialize Rust type {rust_name} into CQL type {got:?}: {kind}")]
1109pub struct BuiltinSerializationError {
1110 pub rust_name: &'static str,
1112
1113 pub got: ColumnType<'static>,
1115
1116 pub kind: BuiltinSerializationErrorKind,
1118}
1119
1120pub(crate) fn mk_ser_err<T: ?Sized>(
1121 got: &ColumnType,
1122 kind: impl Into<BuiltinSerializationErrorKind>,
1123) -> SerializationError {
1124 mk_ser_err_named(std::any::type_name::<T>(), got, kind)
1125}
1126
1127fn mk_ser_err_named(
1128 name: &'static str,
1129 got: &ColumnType,
1130 kind: impl Into<BuiltinSerializationErrorKind>,
1131) -> SerializationError {
1132 SerializationError::new(BuiltinSerializationError {
1133 rust_name: name,
1134 got: got.clone().into_owned(),
1135 kind: kind.into(),
1136 })
1137}
1138
1139#[derive(Debug, Clone)]
1141#[non_exhaustive]
1142pub enum BuiltinTypeCheckErrorKind {
1143 MismatchedType {
1145 expected: &'static [ColumnType<'static>],
1147 },
1148
1149 NotEmptyable,
1151
1152 SetOrListError(SetOrListTypeCheckErrorKind),
1154
1155 MapError(MapTypeCheckErrorKind),
1157
1158 TupleError(TupleTypeCheckErrorKind),
1160
1161 UdtError(UdtTypeCheckErrorKind),
1163}
1164
1165impl From<SetOrListTypeCheckErrorKind> for BuiltinTypeCheckErrorKind {
1166 fn from(value: SetOrListTypeCheckErrorKind) -> Self {
1167 BuiltinTypeCheckErrorKind::SetOrListError(value)
1168 }
1169}
1170
1171impl From<MapTypeCheckErrorKind> for BuiltinTypeCheckErrorKind {
1172 fn from(value: MapTypeCheckErrorKind) -> Self {
1173 BuiltinTypeCheckErrorKind::MapError(value)
1174 }
1175}
1176
1177impl From<TupleTypeCheckErrorKind> for BuiltinTypeCheckErrorKind {
1178 fn from(value: TupleTypeCheckErrorKind) -> Self {
1179 BuiltinTypeCheckErrorKind::TupleError(value)
1180 }
1181}
1182
1183impl From<UdtTypeCheckErrorKind> for BuiltinTypeCheckErrorKind {
1184 fn from(value: UdtTypeCheckErrorKind) -> Self {
1185 BuiltinTypeCheckErrorKind::UdtError(value)
1186 }
1187}
1188
1189impl Display for BuiltinTypeCheckErrorKind {
1190 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1191 match self {
1192 BuiltinTypeCheckErrorKind::MismatchedType { expected } => {
1193 write!(f, "expected one of the CQL types: {expected:?}")
1194 }
1195 BuiltinTypeCheckErrorKind::NotEmptyable => {
1196 f.write_str("the separate empty representation is not valid for this type")
1197 }
1198 BuiltinTypeCheckErrorKind::SetOrListError(err) => err.fmt(f),
1199 BuiltinTypeCheckErrorKind::MapError(err) => err.fmt(f),
1200 BuiltinTypeCheckErrorKind::TupleError(err) => err.fmt(f),
1201 BuiltinTypeCheckErrorKind::UdtError(err) => err.fmt(f),
1202 }
1203 }
1204}
1205
1206#[derive(Debug, Clone)]
1208#[non_exhaustive]
1209pub enum BuiltinSerializationErrorKind {
1210 SizeOverflow,
1213
1214 ValueOverflow,
1216
1217 SetOrListError(SetOrListSerializationErrorKind),
1219
1220 VectorError(VectorSerializationErrorKind),
1222
1223 MapError(MapSerializationErrorKind),
1225
1226 TupleError(TupleSerializationErrorKind),
1228
1229 UdtError(UdtSerializationErrorKind),
1231}
1232
1233impl From<SetOrListSerializationErrorKind> for BuiltinSerializationErrorKind {
1234 fn from(value: SetOrListSerializationErrorKind) -> Self {
1235 BuiltinSerializationErrorKind::SetOrListError(value)
1236 }
1237}
1238
1239impl From<VectorSerializationErrorKind> for BuiltinSerializationErrorKind {
1240 fn from(value: VectorSerializationErrorKind) -> Self {
1241 BuiltinSerializationErrorKind::VectorError(value)
1242 }
1243}
1244
1245impl From<MapSerializationErrorKind> for BuiltinSerializationErrorKind {
1246 fn from(value: MapSerializationErrorKind) -> Self {
1247 BuiltinSerializationErrorKind::MapError(value)
1248 }
1249}
1250
1251impl From<TupleSerializationErrorKind> for BuiltinSerializationErrorKind {
1252 fn from(value: TupleSerializationErrorKind) -> Self {
1253 BuiltinSerializationErrorKind::TupleError(value)
1254 }
1255}
1256
1257impl From<UdtSerializationErrorKind> for BuiltinSerializationErrorKind {
1258 fn from(value: UdtSerializationErrorKind) -> Self {
1259 BuiltinSerializationErrorKind::UdtError(value)
1260 }
1261}
1262
1263impl Display for BuiltinSerializationErrorKind {
1264 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1265 match self {
1266 BuiltinSerializationErrorKind::SizeOverflow => {
1267 f.write_str("the Rust value is too big to be serialized in the CQL protocol format")
1268 }
1269 BuiltinSerializationErrorKind::ValueOverflow => {
1270 f.write_str("the Rust value is out of range supported by the CQL type")
1271 }
1272 BuiltinSerializationErrorKind::SetOrListError(err) => err.fmt(f),
1273 BuiltinSerializationErrorKind::VectorError(err) => err.fmt(f),
1274 BuiltinSerializationErrorKind::MapError(err) => err.fmt(f),
1275 BuiltinSerializationErrorKind::TupleError(err) => err.fmt(f),
1276 BuiltinSerializationErrorKind::UdtError(err) => err.fmt(f),
1277 }
1278 }
1279}
1280
1281#[derive(Debug, Clone)]
1283#[non_exhaustive]
1284pub enum MapTypeCheckErrorKind {
1285 NotMap,
1287}
1288
1289impl Display for MapTypeCheckErrorKind {
1290 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1291 match self {
1292 MapTypeCheckErrorKind::NotMap => f.write_str(
1293 "the CQL type the Rust type was attempted to be type checked against was not a map",
1294 ),
1295 }
1296 }
1297}
1298
1299#[derive(Debug, Clone)]
1301#[non_exhaustive]
1302pub enum MapSerializationErrorKind {
1303 TooManyElements,
1305
1306 KeySerializationFailed(SerializationError),
1308
1309 ValueSerializationFailed(SerializationError),
1311}
1312
1313impl Display for MapSerializationErrorKind {
1314 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1315 match self {
1316 MapSerializationErrorKind::TooManyElements => {
1317 f.write_str("the map contains too many elements to fit in CQL representation")
1318 }
1319 MapSerializationErrorKind::KeySerializationFailed(err) => {
1320 write!(f, "failed to serialize one of the keys: {err}")
1321 }
1322 MapSerializationErrorKind::ValueSerializationFailed(err) => {
1323 write!(f, "failed to serialize one of the values: {err}")
1324 }
1325 }
1326 }
1327}
1328
1329#[derive(Debug, Clone)]
1331#[non_exhaustive]
1332pub enum SetOrListTypeCheckErrorKind {
1333 NotSetOrList,
1335}
1336
1337impl Display for SetOrListTypeCheckErrorKind {
1338 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1339 match self {
1340 SetOrListTypeCheckErrorKind::NotSetOrList => {
1341 f.write_str("the CQL type the Rust type was attempted to be type checked against was neither a set, nor a list, nor a vector")
1342 }
1343 }
1344 }
1345}
1346
1347#[derive(Debug, Clone)]
1349#[non_exhaustive]
1350pub enum SetOrListSerializationErrorKind {
1351 TooManyElements,
1353
1354 ElementSerializationFailed(SerializationError),
1356}
1357
1358impl Display for SetOrListSerializationErrorKind {
1359 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1360 match self {
1361 SetOrListSerializationErrorKind::TooManyElements => f.write_str(
1362 "the collection contains too many elements to fit in CQL representation",
1363 ),
1364 SetOrListSerializationErrorKind::ElementSerializationFailed(err) => {
1365 write!(f, "failed to serialize one of the elements: {err}")
1366 }
1367 }
1368 }
1369}
1370
1371#[derive(Error, Debug, Clone)]
1373#[non_exhaustive]
1374pub enum VectorSerializationErrorKind {
1375 #[error(
1378 "number of vector elements ({0}) does not match the number of declared dimensions ({1})"
1379 )]
1380 InvalidNumberOfElements(usize, u16),
1381
1382 #[error("failed to serialize one of the elements: {0}")]
1384 ElementSerializationFailed(SerializationError),
1385}
1386
1387#[derive(Debug, Clone)]
1389#[non_exhaustive]
1390pub enum TupleTypeCheckErrorKind {
1391 NotTuple,
1393
1394 WrongElementCount {
1400 rust_type_el_count: usize,
1402
1403 cql_type_el_count: usize,
1405 },
1406}
1407
1408impl Display for TupleTypeCheckErrorKind {
1409 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1410 match self {
1411 TupleTypeCheckErrorKind::NotTuple => f.write_str(
1412 "the CQL type the Rust type was attempted to be type checked against is not a tuple"
1413 ),
1414 TupleTypeCheckErrorKind::WrongElementCount { rust_type_el_count, cql_type_el_count } => write!(
1415 f,
1416 "wrong tuple element count: CQL type has {cql_type_el_count}, the Rust tuple has {rust_type_el_count}"
1417 ),
1418 }
1419 }
1420}
1421
1422#[derive(Debug, Clone)]
1424#[non_exhaustive]
1425pub enum TupleSerializationErrorKind {
1426 ElementSerializationFailed {
1428 index: usize,
1430
1431 err: SerializationError,
1433 },
1434}
1435
1436impl Display for TupleSerializationErrorKind {
1437 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1438 match self {
1439 TupleSerializationErrorKind::ElementSerializationFailed { index, err } => {
1440 write!(f, "element no. {index} failed to serialize: {err}")
1441 }
1442 }
1443 }
1444}
1445
1446#[derive(Debug, Clone)]
1448#[non_exhaustive]
1449pub enum UdtTypeCheckErrorKind {
1450 NotUdt,
1452
1453 NameMismatch {
1455 keyspace: String,
1457
1458 type_name: String,
1460 },
1461
1462 ValueMissingForUdtField {
1464 field_name: String,
1466 },
1467
1468 NoSuchFieldInUdt {
1470 field_name: String,
1472 },
1473
1474 FieldNameMismatch {
1476 rust_field_name: String,
1478
1479 db_field_name: String,
1481 },
1482}
1483
1484impl Display for UdtTypeCheckErrorKind {
1485 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1486 match self {
1487 UdtTypeCheckErrorKind::NotUdt => f.write_str("the CQL type the Rust type was attempted to be type checked against is not a UDT"),
1488 UdtTypeCheckErrorKind::NameMismatch {
1489 keyspace,
1490 type_name,
1491 } => write!(
1492 f,
1493 "the Rust UDT name does not match the actual CQL UDT name ({keyspace}.{type_name})"
1494 ),
1495 UdtTypeCheckErrorKind::ValueMissingForUdtField { field_name } => {
1496 write!(f, "the field {field_name} is missing in the Rust data but is required by the CQL UDT type")
1497 }
1498 UdtTypeCheckErrorKind::NoSuchFieldInUdt { field_name } => write!(
1499 f,
1500 "the field {field_name} that is present in the Rust data is not present in the CQL type"
1501 ),
1502 UdtTypeCheckErrorKind::FieldNameMismatch { rust_field_name, db_field_name } => write!(
1503 f,
1504 "expected field with name {db_field_name} at given position, but the Rust field name is {rust_field_name}"
1505 ),
1506 }
1507 }
1508}
1509
1510#[derive(Debug, Clone)]
1512#[non_exhaustive]
1513pub enum UdtSerializationErrorKind {
1514 FieldSerializationFailed {
1516 field_name: String,
1518
1519 err: SerializationError,
1521 },
1522}
1523
1524impl Display for UdtSerializationErrorKind {
1525 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1526 match self {
1527 UdtSerializationErrorKind::FieldSerializationFailed { field_name, err } => {
1528 write!(f, "field {field_name} failed to serialize: {err}")
1529 }
1530 }
1531 }
1532}
1533
1534mod doctests {
1535 fn _test_udt_bad_attributes_skip_name_check_requires_enforce_order() {}
1542
1543 fn _test_udt_bad_attributes_skip_name_check_conflicts_with_rename() {}
1553
1554 fn _test_udt_bad_attributes_rename_collision_with_field() {}
1565
1566 fn _test_udt_bad_attributes_rename_collision_with_another_rename() {}
1578
1579 fn _test_udt_bad_attributes_name_skip_name_checks_limitations_on_allow_missing() {}
1591
1592 fn _test_udt_good_attributes_name_skip_name_checks_limitations_on_allow_missing() {}
1605
1606 fn _test_udt_unordered_flavour_no_limitations_on_allow_missing() {}
1617
1618 fn _test_udt_default_when_null_is_accepted() {}
1629}
1630
1631#[cfg(test)]
1632#[path = "value_tests.rs"]
1633pub(crate) mod tests;