1use std::collections::{BTreeMap, HashSet};
7use std::fmt::Display;
8use std::hash::BuildHasher;
9use std::{collections::HashMap, sync::Arc};
10
11use bytes::BufMut;
12use thiserror::Error;
13
14use crate::frame::request::RequestDeserializationError;
15use crate::frame::response::result::ColumnType;
16use crate::frame::response::result::PreparedMetadata;
17use crate::frame::types;
18use crate::frame::{response::result::ColumnSpec, types::RawValue};
19
20use super::value::SerializeValue;
21use super::{CellWriter, RowWriter, SerializationError};
22
23pub struct RowSerializationContext<'a> {
25 pub(crate) columns: &'a [ColumnSpec<'a>],
26}
27
28impl<'a> RowSerializationContext<'a> {
29 #[inline]
31 pub fn from_prepared(prepared: &'a PreparedMetadata) -> Self {
32 Self {
33 columns: prepared.col_specs.as_slice(),
34 }
35 }
36
37 #[inline]
39 pub fn from_specs(specs: &'a [ColumnSpec<'a>]) -> Self {
40 Self { columns: specs }
41 }
42
43 #[inline]
46 pub const fn empty() -> Self {
47 Self { columns: &[] }
48 }
49
50 #[inline]
52 pub fn columns(&self) -> &'a [ColumnSpec] {
53 self.columns
54 }
55}
56
57pub trait SerializeRow {
64 fn serialize(
69 &self,
70 ctx: &RowSerializationContext<'_>,
71 writer: &mut RowWriter,
72 ) -> Result<(), SerializationError>;
73
74 fn is_empty(&self) -> bool;
82}
83
84macro_rules! impl_serialize_row_for_unit {
85 () => {
86 fn serialize(
87 &self,
88 ctx: &RowSerializationContext<'_>,
89 _writer: &mut RowWriter,
90 ) -> Result<(), SerializationError> {
91 if !ctx.columns().is_empty() {
92 return Err(mk_typck_err::<Self>(
93 BuiltinTypeCheckErrorKind::WrongColumnCount {
94 rust_cols: 0,
95 cql_cols: ctx.columns().len(),
96 },
97 ));
98 }
99 Ok(())
101 }
102
103 #[inline]
104 fn is_empty(&self) -> bool {
105 true
106 }
107 };
108}
109
110impl SerializeRow for () {
111 impl_serialize_row_for_unit!();
112}
113
114impl SerializeRow for [u8; 0] {
115 impl_serialize_row_for_unit!();
116}
117
118macro_rules! impl_serialize_row_for_slice {
119 () => {
120 fn serialize(
121 &self,
122 ctx: &RowSerializationContext<'_>,
123 writer: &mut RowWriter,
124 ) -> Result<(), SerializationError> {
125 if ctx.columns().len() != self.len() {
126 return Err(mk_typck_err::<Self>(
127 BuiltinTypeCheckErrorKind::WrongColumnCount {
128 rust_cols: self.len(),
129 cql_cols: ctx.columns().len(),
130 },
131 ));
132 }
133 for (col, val) in ctx.columns().iter().zip(self.iter()) {
134 $crate::_macro_internal::ser::row::serialize_column::<Self>(val, col, writer)?;
135 }
136 Ok(())
137 }
138
139 #[inline]
140 fn is_empty(&self) -> bool {
141 <[T]>::is_empty(self.as_ref())
142 }
143 };
144}
145
146impl<'a, T: SerializeValue + 'a> SerializeRow for &'a [T] {
147 impl_serialize_row_for_slice!();
148}
149
150impl<T: SerializeValue> SerializeRow for Vec<T> {
151 impl_serialize_row_for_slice!();
152}
153
154impl<T: SerializeRow + ?Sized> SerializeRow for Box<T> {
155 #[inline]
156 fn serialize(
157 &self,
158 ctx: &RowSerializationContext<'_>,
159 writer: &mut RowWriter,
160 ) -> Result<(), SerializationError> {
161 self.as_ref().serialize(ctx, writer)
162 }
163
164 #[inline]
165 fn is_empty(&self) -> bool {
166 self.as_ref().is_empty()
167 }
168}
169
170macro_rules! impl_serialize_row_for_map {
171 () => {
172 fn serialize(
173 &self,
174 ctx: &RowSerializationContext<'_>,
175 writer: &mut RowWriter,
176 ) -> Result<(), SerializationError> {
177 let mut unused_columns: HashSet<&str> = self.keys().map(|k| k.as_ref()).collect();
181
182 for col in ctx.columns.iter() {
183 match self.get(col.name()) {
184 None => {
185 return Err(mk_typck_err::<Self>(
186 BuiltinTypeCheckErrorKind::ValueMissingForColumn {
187 name: col.name().to_owned(),
188 },
189 ))
190 }
191 Some(v) => {
192 $crate::_macro_internal::ser::row::serialize_column::<Self>(
193 v, col, writer,
194 )?;
195 let _ = unused_columns.remove(col.name());
196 }
197 }
198 }
199
200 if !unused_columns.is_empty() {
201 let name = unused_columns.iter().min().unwrap();
203 return Err(mk_typck_err::<Self>(
204 BuiltinTypeCheckErrorKind::NoColumnWithName {
205 name: name.to_string(),
206 },
207 ));
208 }
209
210 Ok(())
211 }
212
213 #[inline]
214 fn is_empty(&self) -> bool {
215 Self::is_empty(self)
216 }
217 };
218}
219
220impl<T: SerializeValue> SerializeRow for BTreeMap<String, T> {
221 impl_serialize_row_for_map!();
222}
223
224impl<T: SerializeValue> SerializeRow for BTreeMap<&str, T> {
225 impl_serialize_row_for_map!();
226}
227
228impl<T: SerializeValue, S: BuildHasher> SerializeRow for HashMap<String, T, S> {
229 impl_serialize_row_for_map!();
230}
231
232impl<T: SerializeValue, S: BuildHasher> SerializeRow for HashMap<&str, T, S> {
233 impl_serialize_row_for_map!();
234}
235
236impl<T: SerializeRow + ?Sized> SerializeRow for &T {
237 fn serialize(
238 &self,
239 ctx: &RowSerializationContext<'_>,
240 writer: &mut RowWriter,
241 ) -> Result<(), SerializationError> {
242 <T as SerializeRow>::serialize(self, ctx, writer)
243 }
244
245 #[inline]
246 fn is_empty(&self) -> bool {
247 <T as SerializeRow>::is_empty(self)
248 }
249}
250
251macro_rules! impl_tuple {
252 (
253 $($typs:ident),*;
254 $($fidents:ident),*;
255 $($tidents:ident),*;
256 $length:expr
257 ) => {
258 impl<$($typs: SerializeValue),*> SerializeRow for ($($typs,)*) {
259 fn serialize(
260 &self,
261 ctx: &RowSerializationContext<'_>,
262 writer: &mut RowWriter,
263 ) -> Result<(), SerializationError> {
264 let ($($tidents,)*) = match ctx.columns() {
265 [$($tidents),*] => ($($tidents,)*),
266 _ => return Err(mk_typck_err::<Self>(
267 BuiltinTypeCheckErrorKind::WrongColumnCount {
268 rust_cols: $length,
269 cql_cols: ctx.columns().len(),
270 },
271 )),
272 };
273 let ($($fidents,)*) = self;
274 $(
275 $crate::_macro_internal::ser::row::serialize_column::<Self>($fidents, $tidents, writer)?;
276 )*
277 Ok(())
278 }
279
280 #[inline]
281 fn is_empty(&self) -> bool {
282 $length == 0
283 }
284 }
285 };
286}
287
288macro_rules! impl_tuples {
289 (;;;$length:expr) => {};
290 (
291 $typ:ident$(, $($typs:ident),*)?;
292 $fident:ident$(, $($fidents:ident),*)?;
293 $tident:ident$(, $($tidents:ident),*)?;
294 $length:expr
295 ) => {
296 impl_tuples!(
297 $($($typs),*)?;
298 $($($fidents),*)?;
299 $($($tidents),*)?;
300 $length - 1
301 );
302 impl_tuple!(
303 $typ$(, $($typs),*)?;
304 $fident$(, $($fidents),*)?;
305 $tident$(, $($tidents),*)?;
306 $length
307 );
308 };
309}
310
311impl_tuples!(
312 T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15;
313 f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15;
314 t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15;
315 16
316);
317
318#[derive(Debug, Error, Clone)]
321#[error("Failed to type check query arguments {rust_name}: {kind}")]
322pub struct BuiltinTypeCheckError {
323 pub rust_name: &'static str,
325
326 pub kind: BuiltinTypeCheckErrorKind,
328}
329
330#[doc(hidden)]
331pub fn mk_typck_err<T>(kind: impl Into<BuiltinTypeCheckErrorKind>) -> SerializationError {
332 mk_typck_err_named(std::any::type_name::<T>(), kind)
333}
334
335fn mk_typck_err_named(
336 name: &'static str,
337 kind: impl Into<BuiltinTypeCheckErrorKind>,
338) -> SerializationError {
339 SerializationError::new(BuiltinTypeCheckError {
340 rust_name: name,
341 kind: kind.into(),
342 })
343}
344
345#[derive(Debug, Error, Clone)]
348#[error("Failed to serialize query arguments {rust_name}: {kind}")]
349pub struct BuiltinSerializationError {
350 pub rust_name: &'static str,
352
353 pub kind: BuiltinSerializationErrorKind,
355}
356
357pub(crate) fn mk_ser_err<T>(kind: impl Into<BuiltinSerializationErrorKind>) -> SerializationError {
358 mk_ser_err_named(std::any::type_name::<T>(), kind)
359}
360
361fn mk_ser_err_named(
362 name: &'static str,
363 kind: impl Into<BuiltinSerializationErrorKind>,
364) -> SerializationError {
365 SerializationError::new(BuiltinSerializationError {
366 rust_name: name,
367 kind: kind.into(),
368 })
369}
370
371#[derive(Debug, Clone)]
373#[non_exhaustive]
374pub enum BuiltinTypeCheckErrorKind {
375 WrongColumnCount {
377 rust_cols: usize,
379
380 cql_cols: usize,
382 },
383
384 NoColumnWithName {
387 name: String,
389 },
390
391 ValueMissingForColumn {
393 name: String,
396 },
397
398 ColumnNameMismatch {
400 rust_column_name: String,
402
403 db_column_name: String,
405 },
406}
407
408impl Display for BuiltinTypeCheckErrorKind {
409 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
410 match self {
411 BuiltinTypeCheckErrorKind::WrongColumnCount { rust_cols, cql_cols } => {
412 write!(f, "wrong column count: the statement operates on {cql_cols} columns, but the given rust type provides {rust_cols}")
413 }
414 BuiltinTypeCheckErrorKind::NoColumnWithName { name } => {
415 write!(
416 f,
417 "value for column {name} was provided, but there is no bind marker for this column in the query"
418 )
419 }
420 BuiltinTypeCheckErrorKind::ValueMissingForColumn { name } => {
421 write!(
422 f,
423 "value for column {name} was not provided, but the query requires it"
424 )
425 }
426 BuiltinTypeCheckErrorKind::ColumnNameMismatch { rust_column_name, db_column_name } => write!(
427 f,
428 "expected column with name {db_column_name} at given position, but the Rust field name is {rust_column_name}"
429 ),
430 }
431 }
432}
433
434#[derive(Debug, Clone)]
436#[non_exhaustive]
437pub enum BuiltinSerializationErrorKind {
438 ColumnSerializationFailed {
440 name: String,
442
443 err: SerializationError,
445 },
446 TooManyValues,
448}
449
450impl Display for BuiltinSerializationErrorKind {
451 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
452 match self {
453 BuiltinSerializationErrorKind::ColumnSerializationFailed { name, err } => {
454 write!(f, "failed to serialize column {name}: {err}")
455 }
456 BuiltinSerializationErrorKind::TooManyValues => {
457 write!(
458 f,
459 "Too many values to add, max 65,535 values can be sent in a request"
460 )
461 }
462 }
463 }
464}
465
466#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
474pub struct SerializedValues {
475 serialized_values: Vec<u8>,
476 element_count: u16,
477}
478
479impl SerializedValues {
480 pub const fn new() -> Self {
482 SerializedValues {
483 serialized_values: Vec::new(),
484 element_count: 0,
485 }
486 }
487
488 pub const EMPTY: &'static SerializedValues = &SerializedValues::new();
490
491 pub fn from_serializable<T: SerializeRow + ?Sized>(
493 ctx: &RowSerializationContext,
494 row: &T,
495 ) -> Result<Self, SerializationError> {
496 Self::from_closure(|writer| row.serialize(ctx, writer)).map(|(sr, _)| sr)
497 }
498
499 pub fn from_closure<F, R>(f: F) -> Result<(Self, R), SerializationError>
501 where
502 F: FnOnce(&mut RowWriter) -> Result<R, SerializationError>,
503 {
504 let mut data = Vec::new();
505 let mut writer = RowWriter::new(&mut data);
506 let ret = f(&mut writer)?;
507 let element_count = match writer.value_count().try_into() {
508 Ok(n) => n,
509 Err(_) => {
510 return Err(SerializationError(Arc::new(mk_ser_err::<Self>(
511 BuiltinSerializationErrorKind::TooManyValues,
512 ))));
513 }
514 };
515
516 Ok((
517 SerializedValues {
518 serialized_values: data,
519 element_count,
520 },
521 ret,
522 ))
523 }
524
525 #[inline]
527 pub fn is_empty(&self) -> bool {
528 self.element_count() == 0
529 }
530
531 #[inline]
533 pub fn iter(&self) -> impl Iterator<Item = RawValue> {
534 SerializedValuesIterator {
535 serialized_values: &self.serialized_values,
536 }
537 }
538
539 #[inline]
541 pub fn element_count(&self) -> u16 {
542 self.element_count
543 }
544
545 #[inline]
547 pub fn buffer_size(&self) -> usize {
548 self.serialized_values.len()
549 }
550
551 pub(crate) fn write_to_request(&self, buf: &mut impl BufMut) {
552 buf.put_u16(self.element_count);
553 buf.put(self.serialized_values.as_slice())
554 }
555
556 pub(crate) fn get_contents(&self) -> &[u8] {
558 &self.serialized_values
559 }
560
561 pub fn add_value<T: SerializeValue>(
563 &mut self,
564 val: &T,
565 typ: &ColumnType,
566 ) -> Result<(), SerializationError> {
567 if self.element_count() == u16::MAX {
568 return Err(SerializationError(Arc::new(mk_ser_err::<Self>(
569 BuiltinSerializationErrorKind::TooManyValues,
570 ))));
571 }
572
573 let len_before_serialize: usize = self.serialized_values.len();
574
575 let writer = CellWriter::new(&mut self.serialized_values);
576 if let Err(e) = val.serialize(typ, writer) {
577 self.serialized_values.resize(len_before_serialize, 0);
578 Err(e)
579 } else {
580 self.element_count += 1;
581 Ok(())
582 }
583 }
584
585 pub(crate) fn new_from_frame(buf: &mut &[u8]) -> Result<Self, RequestDeserializationError> {
588 let values_num = types::read_short(buf)?;
589 let values_beg = *buf;
590 for _ in 0..values_num {
591 let _serialized = types::read_value(buf)?;
592 }
593
594 let values_len_in_buf = values_beg.len() - buf.len();
595 let values_in_frame = &values_beg[0..values_len_in_buf];
596 Ok(SerializedValues {
597 serialized_values: values_in_frame.to_vec(),
598 element_count: values_num,
599 })
600 }
601}
602
603impl Default for SerializedValues {
604 fn default() -> Self {
605 Self::new()
606 }
607}
608
609#[derive(Clone, Copy)]
611pub struct SerializedValuesIterator<'a> {
612 serialized_values: &'a [u8],
613}
614
615impl<'a> Iterator for SerializedValuesIterator<'a> {
616 type Item = RawValue<'a>;
617
618 fn next(&mut self) -> Option<Self::Item> {
619 if self.serialized_values.is_empty() {
620 return None;
621 }
622
623 Some(types::read_value(&mut self.serialized_values).expect("badly encoded value"))
624 }
625}
626
627mod doctests {
628
629 fn _test_struct_deserialization_name_check_skip_requires_enforce_order() {}
636
637 fn _test_struct_deserialization_skip_name_check_conflicts_with_rename() {}
647
648 fn _test_struct_deserialization_skip_rename_collision_with_field() {}
659
660 fn _test_struct_deserialization_rename_collision_with_another_rename() {}
672}
673
674#[cfg(test)]
675#[path = "row_tests.rs"]
676pub(crate) mod tests;