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