From 6bab9215667e097379a98558d5bb1af6b30a6526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20Przytu=C5=82a?= Date: Fri, 6 Dec 2024 10:39:32 +0100 Subject: [PATCH] codewide: deprecate legacy serialization API's items Items constituting the legacy serialization API hadn't been marked with the #[deprecated] attribute. As we're going to remove them soon, let's warn users about that explicitly. I recommend viewing this commit with whitespace changes ignored. --- scylla-cql/src/frame/response/result.rs | 1 + scylla-cql/src/frame/value.rs | 1855 ++++++++++++----------- scylla-cql/src/frame/value_tests.rs | 3 + scylla-cql/src/lib.rs | 3 + scylla-cql/src/types/serialize/batch.rs | 11 + scylla-cql/src/types/serialize/row.rs | 30 +- scylla-cql/src/types/serialize/value.rs | 24 + scylla/src/lib.rs | 3 + scylla/src/macros.rs | 11 + 9 files changed, 1078 insertions(+), 863 deletions(-) diff --git a/scylla-cql/src/frame/response/result.rs b/scylla-cql/src/frame/response/result.rs index 2c5a76e29..39bf0730c 100644 --- a/scylla-cql/src/frame/response/result.rs +++ b/scylla-cql/src/frame/response/result.rs @@ -2475,6 +2475,7 @@ mod tests { ); } + #[allow(deprecated)] #[test] fn test_serialize_empty() { use crate::frame::value::Value; diff --git a/scylla-cql/src/frame/value.rs b/scylla-cql/src/frame/value.rs index a6b6c1c7f..d22ef614b 100644 --- a/scylla-cql/src/frame/value.rs +++ b/scylla-cql/src/frame/value.rs @@ -12,20 +12,31 @@ use super::response::result::CqlValue; use super::types::vint_encode; use super::types::RawValue; -/// Every value being sent in a query must implement this trait -/// serialize() should write the Value as [bytes] to the provided buffer -pub trait Value { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig>; -} - #[derive(Debug, Error, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] #[error("Value too big to be sent in a request - max 2GiB allowed")] +#[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" +)] pub struct ValueTooBig; #[derive(Debug, Error, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] #[error("Value is too large to fit in the CQL type")] pub struct ValueOverflow; +#[allow(deprecated)] +#[derive(Debug, Error, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub enum SerializeValuesError { + #[error("Too many values to add, max 65,535 values can be sent in a request")] + TooManyValues, + #[error("Mixing named and not named values is not allowed")] + MixingNamedAndNotNamedValues, + #[error(transparent)] + ValueTooBig(#[from] ValueTooBig), + #[error("Parsing serialized values failed")] + ParseError, +} + /// Represents an unset value #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct Unset; @@ -650,15 +661,6 @@ impl TryInto for CqlTime { } } -/// Keeps a buffer with serialized Values -/// Allows adding new Values and iterating over serialized ones -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct LegacySerializedValues { - serialized_values: Vec, - values_num: u16, - contains_names: bool, -} - /// Represents a CQL Duration value #[derive(Clone, Debug, Copy, PartialEq, Eq)] pub struct CqlDuration { @@ -667,754 +669,863 @@ pub struct CqlDuration { pub nanoseconds: i64, } -#[derive(Debug, Error, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub enum SerializeValuesError { - #[error("Too many values to add, max 65,535 values can be sent in a request")] - TooManyValues, - #[error("Mixing named and not named values is not allowed")] - MixingNamedAndNotNamedValues, - #[error(transparent)] - ValueTooBig(#[from] ValueTooBig), - #[error("Parsing serialized values failed")] - ParseError, -} - -pub type SerializedResult<'a> = Result, SerializeValuesError>; - -/// Represents list of values to be sent in a query -/// gets serialized and but into request -pub trait ValueList { - /// Provides a view of ValueList as LegacySerializedValues - /// returns `Cow` to make impl ValueList for LegacySerializedValues efficient - fn serialized(&self) -> SerializedResult<'_>; - - fn write_to_request(&self, buf: &mut impl BufMut) -> Result<(), SerializeValuesError> { - let serialized = self.serialized()?; - LegacySerializedValues::write_to_request(&serialized, buf); - - Ok(()) +#[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" +)] +mod legacy { + #![allow(deprecated)] + + use super::*; + + /// Every value being sent in a query must implement this trait + /// serialize() should write the Value as [bytes] to the provided buffer + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub trait Value { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig>; + } + + /// Keeps a buffer with serialized Values + /// Allows adding new Values and iterating over serialized ones + #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] + pub struct LegacySerializedValues { + serialized_values: Vec, + values_num: u16, + contains_names: bool, + } + + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub type SerializedResult<'a> = Result, SerializeValuesError>; + + /// Represents list of values to be sent in a query + /// gets serialized and but into request + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub trait ValueList { + /// Provides a view of ValueList as LegacySerializedValues + /// returns `Cow` to make impl ValueList for LegacySerializedValues efficient + fn serialized(&self) -> SerializedResult<'_>; + + fn write_to_request(&self, buf: &mut impl BufMut) -> Result<(), SerializeValuesError> { + let serialized = self.serialized()?; + LegacySerializedValues::write_to_request(&serialized, buf); + + Ok(()) + } } -} -impl Default for LegacySerializedValues { - fn default() -> Self { - Self::new() + impl Default for LegacySerializedValues { + fn default() -> Self { + Self::new() + } } -} -impl LegacySerializedValues { - /// Creates empty value list - pub const fn new() -> Self { - LegacySerializedValues { - serialized_values: Vec::new(), - values_num: 0, - contains_names: false, + impl LegacySerializedValues { + /// Creates empty value list + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub const fn new() -> Self { + LegacySerializedValues { + serialized_values: Vec::new(), + values_num: 0, + contains_names: false, + } } - } - pub fn with_capacity(capacity: usize) -> Self { - LegacySerializedValues { - serialized_values: Vec::with_capacity(capacity), - values_num: 0, - contains_names: false, + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub fn with_capacity(capacity: usize) -> Self { + LegacySerializedValues { + serialized_values: Vec::with_capacity(capacity), + values_num: 0, + contains_names: false, + } } - } - pub fn has_names(&self) -> bool { - self.contains_names - } + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub fn has_names(&self) -> bool { + self.contains_names + } - /// A const empty instance, useful for taking references - pub const EMPTY: &'static LegacySerializedValues = &LegacySerializedValues::new(); + /// A const empty instance, useful for taking references + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub const EMPTY: &'static LegacySerializedValues = &LegacySerializedValues::new(); + + /// Serializes value and appends it to the list + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub fn add_value(&mut self, val: &impl Value) -> Result<(), SerializeValuesError> { + if self.contains_names { + return Err(SerializeValuesError::MixingNamedAndNotNamedValues); + } + if self.values_num == u16::MAX { + return Err(SerializeValuesError::TooManyValues); + } - /// Serializes value and appends it to the list - pub fn add_value(&mut self, val: &impl Value) -> Result<(), SerializeValuesError> { - if self.contains_names { - return Err(SerializeValuesError::MixingNamedAndNotNamedValues); - } - if self.values_num == u16::MAX { - return Err(SerializeValuesError::TooManyValues); - } + let len_before_serialize: usize = self.serialized_values.len(); - let len_before_serialize: usize = self.serialized_values.len(); + if let Err(e) = val.serialize(&mut self.serialized_values) { + self.serialized_values.resize(len_before_serialize, 0); + return Err(SerializeValuesError::from(e)); + } - if let Err(e) = val.serialize(&mut self.serialized_values) { - self.serialized_values.resize(len_before_serialize, 0); - return Err(SerializeValuesError::from(e)); + self.values_num += 1; + Ok(()) } - self.values_num += 1; - Ok(()) - } + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub fn add_named_value( + &mut self, + name: &str, + val: &impl Value, + ) -> Result<(), SerializeValuesError> { + if self.values_num > 0 && !self.contains_names { + return Err(SerializeValuesError::MixingNamedAndNotNamedValues); + } + self.contains_names = true; + if self.values_num == u16::MAX { + return Err(SerializeValuesError::TooManyValues); + } - pub fn add_named_value( - &mut self, - name: &str, - val: &impl Value, - ) -> Result<(), SerializeValuesError> { - if self.values_num > 0 && !self.contains_names { - return Err(SerializeValuesError::MixingNamedAndNotNamedValues); - } - self.contains_names = true; - if self.values_num == u16::MAX { - return Err(SerializeValuesError::TooManyValues); - } + let len_before_serialize: usize = self.serialized_values.len(); - let len_before_serialize: usize = self.serialized_values.len(); + types::write_string(name, &mut self.serialized_values) + .map_err(|_| SerializeValuesError::ParseError)?; - types::write_string(name, &mut self.serialized_values) - .map_err(|_| SerializeValuesError::ParseError)?; + if let Err(e) = val.serialize(&mut self.serialized_values) { + self.serialized_values.resize(len_before_serialize, 0); + return Err(SerializeValuesError::from(e)); + } - if let Err(e) = val.serialize(&mut self.serialized_values) { - self.serialized_values.resize(len_before_serialize, 0); - return Err(SerializeValuesError::from(e)); + self.values_num += 1; + Ok(()) } - self.values_num += 1; - Ok(()) - } + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub fn iter(&self) -> impl Iterator { + LegacySerializedValuesIterator { + serialized_values: &self.serialized_values, + contains_names: self.contains_names, + } + } - pub fn iter(&self) -> impl Iterator { - LegacySerializedValuesIterator { - serialized_values: &self.serialized_values, - contains_names: self.contains_names, + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub fn write_to_request(&self, buf: &mut impl BufMut) { + buf.put_u16(self.values_num); + buf.put(&self.serialized_values[..]); } - } - pub fn write_to_request(&self, buf: &mut impl BufMut) { - buf.put_u16(self.values_num); - buf.put(&self.serialized_values[..]); - } + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub fn is_empty(&self) -> bool { + self.values_num == 0 + } - pub fn is_empty(&self) -> bool { - self.values_num == 0 - } + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub fn len(&self) -> u16 { + self.values_num + } - pub fn len(&self) -> u16 { - self.values_num - } + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub fn size(&self) -> usize { + self.serialized_values.len() + } - pub fn size(&self) -> usize { - self.serialized_values.len() + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub fn iter_name_value_pairs(&self) -> impl Iterator, RawValue)> { + let mut buf = &self.serialized_values[..]; + (0..self.values_num).map(move |_| { + // `unwrap()`s here are safe, as we assume type-safety: if `LegacySerializedValues` exits, + // we have a guarantee that the layout of the serialized values is valid. + let name = self + .contains_names + .then(|| types::read_string(&mut buf).unwrap()); + let serialized = types::read_value(&mut buf).unwrap(); + (name, serialized) + }) + } } - pub fn iter_name_value_pairs(&self) -> impl Iterator, RawValue)> { - let mut buf = &self.serialized_values[..]; - (0..self.values_num).map(move |_| { - // `unwrap()`s here are safe, as we assume type-safety: if `LegacySerializedValues` exits, - // we have a guarantee that the layout of the serialized values is valid. - let name = self - .contains_names - .then(|| types::read_string(&mut buf).unwrap()); - let serialized = types::read_value(&mut buf).unwrap(); - (name, serialized) - }) + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + #[derive(Clone, Copy)] + pub struct LegacySerializedValuesIterator<'a> { + serialized_values: &'a [u8], + contains_names: bool, } -} -#[derive(Clone, Copy)] -pub struct LegacySerializedValuesIterator<'a> { - serialized_values: &'a [u8], - contains_names: bool, -} + impl<'a> Iterator for LegacySerializedValuesIterator<'a> { + type Item = RawValue<'a>; -impl<'a> Iterator for LegacySerializedValuesIterator<'a> { - type Item = RawValue<'a>; + fn next(&mut self) -> Option { + if self.serialized_values.is_empty() { + return None; + } - fn next(&mut self) -> Option { - if self.serialized_values.is_empty() { - return None; - } + // In case of named values, skip names + if self.contains_names { + types::read_short_bytes(&mut self.serialized_values) + .expect("badly encoded value name"); + } - // In case of named values, skip names - if self.contains_names { - types::read_short_bytes(&mut self.serialized_values).expect("badly encoded value name"); + Some(types::read_value(&mut self.serialized_values).expect("badly encoded value")) } + } - Some(types::read_value(&mut self.serialized_values).expect("badly encoded value")) + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + /// Represents List of ValueList for Batch statement + pub trait LegacyBatchValues { + /// For some unknown reason, this type, when not resolved to a concrete type for a given async function, + /// cannot live across await boundaries while maintaining the corresponding future `Send`, unless `'r: 'static` + /// + /// See for more details + type LegacyBatchValuesIter<'r>: LegacyBatchValuesIterator<'r> + where + Self: 'r; + fn batch_values_iter(&self) -> Self::LegacyBatchValuesIter<'_>; } -} -/// Represents List of ValueList for Batch statement -pub trait LegacyBatchValues { - /// For some unknown reason, this type, when not resolved to a concrete type for a given async function, - /// cannot live across await boundaries while maintaining the corresponding future `Send`, unless `'r: 'static` + /// An iterator-like for `ValueList` /// - /// See for more details - type LegacyBatchValuesIter<'r>: LegacyBatchValuesIterator<'r> - where - Self: 'r; - fn batch_values_iter(&self) -> Self::LegacyBatchValuesIter<'_>; -} - -/// An iterator-like for `ValueList` -/// -/// An instance of this can be easily obtained from `IT: Iterator`: that would be -/// `BatchValuesIteratorFromIterator` -/// -/// It's just essentially making methods from `ValueList` accessible instead of being an actual iterator because of -/// compiler limitations that would otherwise be very complex to overcome. -/// (specifically, types being different would require yielding enums for tuple impls) -pub trait LegacyBatchValuesIterator<'a> { - fn next_serialized(&mut self) -> Option>; - fn write_next_to_request( - &mut self, - buf: &mut impl BufMut, - ) -> Option>; - fn skip_next(&mut self) -> Option<()>; - fn count(mut self) -> usize - where - Self: Sized, - { - let mut count = 0; - while self.skip_next().is_some() { - count += 1; + /// An instance of this can be easily obtained from `IT: Iterator`: that would be + /// `BatchValuesIteratorFromIterator` + /// + /// It's just essentially making methods from `ValueList` accessible instead of being an actual iterator because of + /// compiler limitations that would otherwise be very complex to overcome. + /// (specifically, types being different would require yielding enums for tuple impls) + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub trait LegacyBatchValuesIterator<'a> { + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + fn next_serialized(&mut self) -> Option>; + + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + fn write_next_to_request( + &mut self, + buf: &mut impl BufMut, + ) -> Option>; + + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + fn skip_next(&mut self) -> Option<()>; + + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + fn count(mut self) -> usize + where + Self: Sized, + { + let mut count = 0; + while self.skip_next().is_some() { + count += 1; + } + count } - count } -} -/// Implements `BatchValuesIterator` from an `Iterator` over references to things that implement `ValueList` -/// -/// Essentially used internally by this lib to provide implementers of `BatchValuesIterator` for cases -/// that always serialize the same concrete `ValueList` type -pub struct LegacyBatchValuesIteratorFromIterator { - it: IT, -} - -impl<'r, 'a: 'r, IT, VL> LegacyBatchValuesIterator<'r> for LegacyBatchValuesIteratorFromIterator -where - IT: Iterator, - VL: ValueList + 'a, -{ - fn next_serialized(&mut self) -> Option> { - self.it.next().map(|vl| vl.serialized()) - } - fn write_next_to_request( - &mut self, - buf: &mut impl BufMut, - ) -> Option> { - self.it.next().map(|vl| vl.write_to_request(buf)) + /// Implements `BatchValuesIterator` from an `Iterator` over references to things that implement `ValueList` + /// + /// Essentially used internally by this lib to provide implementers of `BatchValuesIterator` for cases + /// that always serialize the same concrete `ValueList` type + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub struct LegacyBatchValuesIteratorFromIterator { + it: IT, } - fn skip_next(&mut self) -> Option<()> { - self.it.next().map(|_| ()) + + impl<'r, 'a: 'r, IT, VL> LegacyBatchValuesIterator<'r> for LegacyBatchValuesIteratorFromIterator + where + IT: Iterator, + VL: ValueList + 'a, + { + fn next_serialized(&mut self) -> Option> { + self.it.next().map(|vl| vl.serialized()) + } + fn write_next_to_request( + &mut self, + buf: &mut impl BufMut, + ) -> Option> { + self.it.next().map(|vl| vl.write_to_request(buf)) + } + fn skip_next(&mut self) -> Option<()> { + self.it.next().map(|_| ()) + } } -} -impl From for LegacyBatchValuesIteratorFromIterator -where - IT: Iterator, - IT::Item: ValueList, -{ - fn from(it: IT) -> Self { - LegacyBatchValuesIteratorFromIterator { it } + impl From for LegacyBatchValuesIteratorFromIterator + where + IT: Iterator, + IT::Item: ValueList, + { + fn from(it: IT) -> Self { + LegacyBatchValuesIteratorFromIterator { it } + } } -} -// -// Value impls -// + // + // Value impls + // -// Implement Value for primitive types -impl Value for i8 { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - buf.put_i32(1); - buf.put_i8(*self); - Ok(()) + // Implement Value for primitive types + impl Value for i8 { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + buf.put_i32(1); + buf.put_i8(*self); + Ok(()) + } } -} -impl Value for i16 { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - buf.put_i32(2); - buf.put_i16(*self); - Ok(()) + impl Value for i16 { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + buf.put_i32(2); + buf.put_i16(*self); + Ok(()) + } } -} -impl Value for i32 { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - buf.put_i32(4); - buf.put_i32(*self); - Ok(()) + impl Value for i32 { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + buf.put_i32(4); + buf.put_i32(*self); + Ok(()) + } } -} -impl Value for i64 { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - buf.put_i32(8); - buf.put_i64(*self); - Ok(()) + impl Value for i64 { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + buf.put_i32(8); + buf.put_i64(*self); + Ok(()) + } } -} -impl Value for CqlDecimal { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - let (bytes, scale) = self.as_signed_be_bytes_slice_and_exponent(); + impl Value for CqlDecimal { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + let (bytes, scale) = self.as_signed_be_bytes_slice_and_exponent(); - if bytes.len() > (i32::MAX - 4) as usize { - return Err(ValueTooBig); - } - let serialized_len: i32 = bytes.len() as i32 + 4; + if bytes.len() > (i32::MAX - 4) as usize { + return Err(ValueTooBig); + } + let serialized_len: i32 = bytes.len() as i32 + 4; - buf.put_i32(serialized_len); - buf.put_i32(scale); - buf.extend_from_slice(bytes); + buf.put_i32(serialized_len); + buf.put_i32(scale); + buf.extend_from_slice(bytes); - Ok(()) + Ok(()) + } } -} -#[cfg(feature = "bigdecimal-04")] -impl Value for bigdecimal_04::BigDecimal { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - let (value, scale) = self.as_bigint_and_exponent(); + #[cfg(feature = "bigdecimal-04")] + impl Value for bigdecimal_04::BigDecimal { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + let (value, scale) = self.as_bigint_and_exponent(); - let serialized = value.to_signed_bytes_be(); + let serialized = value.to_signed_bytes_be(); - if serialized.len() > (i32::MAX - 4) as usize { - return Err(ValueTooBig); - } - let serialized_len: i32 = serialized.len() as i32 + 4; + if serialized.len() > (i32::MAX - 4) as usize { + return Err(ValueTooBig); + } + let serialized_len: i32 = serialized.len() as i32 + 4; - buf.put_i32(serialized_len); - buf.put_i32(scale.try_into().map_err(|_| ValueTooBig)?); - buf.extend_from_slice(&serialized); + buf.put_i32(serialized_len); + buf.put_i32(scale.try_into().map_err(|_| ValueTooBig)?); + buf.extend_from_slice(&serialized); - Ok(()) + Ok(()) + } } -} -#[cfg(feature = "chrono-04")] -impl Value for chrono_04::NaiveDate { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - CqlDate::from(*self).serialize(buf) + #[cfg(feature = "chrono-04")] + impl Value for chrono_04::NaiveDate { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + CqlDate::from(*self).serialize(buf) + } } -} -impl Value for CqlDate { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - buf.put_i32(4); - buf.put_u32(self.0); - Ok(()) + impl Value for CqlDate { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + buf.put_i32(4); + buf.put_u32(self.0); + Ok(()) + } } -} -#[cfg(feature = "time-03")] -impl Value for time_03::Date { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - CqlDate::from(*self).serialize(buf) + #[cfg(feature = "time-03")] + impl Value for time_03::Date { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + CqlDate::from(*self).serialize(buf) + } } -} -impl Value for CqlTimestamp { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - buf.put_i32(8); - buf.put_i64(self.0); - Ok(()) + impl Value for CqlTimestamp { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + buf.put_i32(8); + buf.put_i64(self.0); + Ok(()) + } } -} -impl Value for CqlTime { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - buf.put_i32(8); - buf.put_i64(self.0); - Ok(()) + impl Value for CqlTime { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + buf.put_i32(8); + buf.put_i64(self.0); + Ok(()) + } } -} -#[cfg(feature = "chrono-04")] -impl Value for chrono_04::DateTime { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - CqlTimestamp::from(*self).serialize(buf) + #[cfg(feature = "chrono-04")] + impl Value for chrono_04::DateTime { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + CqlTimestamp::from(*self).serialize(buf) + } } -} -#[cfg(feature = "time-03")] -impl Value for time_03::OffsetDateTime { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - CqlTimestamp::from(*self).serialize(buf) + #[cfg(feature = "time-03")] + impl Value for time_03::OffsetDateTime { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + CqlTimestamp::from(*self).serialize(buf) + } } -} -#[cfg(feature = "chrono-04")] -impl Value for chrono_04::NaiveTime { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - CqlTime::try_from(*self) - .map_err(|_| ValueTooBig)? - .serialize(buf) + #[cfg(feature = "chrono-04")] + impl Value for chrono_04::NaiveTime { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + CqlTime::try_from(*self) + .map_err(|_| ValueTooBig)? + .serialize(buf) + } } -} -#[cfg(feature = "time-03")] -impl Value for time_03::Time { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - CqlTime::from(*self).serialize(buf) + #[cfg(feature = "time-03")] + impl Value for time_03::Time { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + CqlTime::from(*self).serialize(buf) + } } -} -#[cfg(feature = "secrecy-08")] -impl Value for secrecy_08::Secret { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - use secrecy_08::ExposeSecret; - self.expose_secret().serialize(buf) + #[cfg(feature = "secrecy-08")] + impl Value for secrecy_08::Secret { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + use secrecy_08::ExposeSecret; + self.expose_secret().serialize(buf) + } } -} -impl Value for bool { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - buf.put_i32(1); - let false_bytes: &[u8] = &[0x00]; - let true_bytes: &[u8] = &[0x01]; - if *self { - buf.put(true_bytes); - } else { - buf.put(false_bytes); - } + impl Value for bool { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + buf.put_i32(1); + let false_bytes: &[u8] = &[0x00]; + let true_bytes: &[u8] = &[0x01]; + if *self { + buf.put(true_bytes); + } else { + buf.put(false_bytes); + } - Ok(()) + Ok(()) + } } -} -impl Value for f32 { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - buf.put_i32(4); - buf.put_f32(*self); - Ok(()) + impl Value for f32 { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + buf.put_i32(4); + buf.put_f32(*self); + Ok(()) + } } -} -impl Value for f64 { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - buf.put_i32(8); - buf.put_f64(*self); - Ok(()) + impl Value for f64 { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + buf.put_i32(8); + buf.put_f64(*self); + Ok(()) + } } -} -impl Value for Uuid { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - buf.put_i32(16); - buf.extend_from_slice(self.as_bytes()); - Ok(()) + impl Value for Uuid { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + buf.put_i32(16); + buf.extend_from_slice(self.as_bytes()); + Ok(()) + } } -} -impl Value for CqlTimeuuid { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - self.0.serialize(buf) + impl Value for CqlTimeuuid { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + self.0.serialize(buf) + } } -} -impl Value for CqlVarint { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - let serialized = &self.0; - let serialized_len: i32 = serialized.len().try_into().map_err(|_| ValueTooBig)?; + impl Value for CqlVarint { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + let serialized = &self.0; + let serialized_len: i32 = serialized.len().try_into().map_err(|_| ValueTooBig)?; - buf.put_i32(serialized_len); - buf.extend_from_slice(serialized); + buf.put_i32(serialized_len); + buf.extend_from_slice(serialized); - Ok(()) + Ok(()) + } } -} -#[cfg(feature = "num-bigint-03")] -impl Value for num_bigint_03::BigInt { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - let serialized = self.to_signed_bytes_be(); - let serialized_len: i32 = serialized.len().try_into().map_err(|_| ValueTooBig)?; + #[cfg(feature = "num-bigint-03")] + impl Value for num_bigint_03::BigInt { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + let serialized = self.to_signed_bytes_be(); + let serialized_len: i32 = serialized.len().try_into().map_err(|_| ValueTooBig)?; - buf.put_i32(serialized_len); - buf.extend_from_slice(&serialized); + buf.put_i32(serialized_len); + buf.extend_from_slice(&serialized); - Ok(()) + Ok(()) + } } -} -#[cfg(feature = "num-bigint-04")] -impl Value for num_bigint_04::BigInt { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - let serialized = self.to_signed_bytes_be(); - let serialized_len: i32 = serialized.len().try_into().map_err(|_| ValueTooBig)?; + #[cfg(feature = "num-bigint-04")] + impl Value for num_bigint_04::BigInt { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + let serialized = self.to_signed_bytes_be(); + let serialized_len: i32 = serialized.len().try_into().map_err(|_| ValueTooBig)?; - buf.put_i32(serialized_len); - buf.extend_from_slice(&serialized); + buf.put_i32(serialized_len); + buf.extend_from_slice(&serialized); - Ok(()) + Ok(()) + } } -} -impl Value for &str { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - let str_bytes: &[u8] = self.as_bytes(); - let val_len: i32 = str_bytes.len().try_into().map_err(|_| ValueTooBig)?; + impl Value for &str { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + let str_bytes: &[u8] = self.as_bytes(); + let val_len: i32 = str_bytes.len().try_into().map_err(|_| ValueTooBig)?; - buf.put_i32(val_len); - buf.put(str_bytes); + buf.put_i32(val_len); + buf.put(str_bytes); - Ok(()) + Ok(()) + } } -} -impl Value for Vec { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - <&[u8] as Value>::serialize(&self.as_slice(), buf) + impl Value for Vec { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + <&[u8] as Value>::serialize(&self.as_slice(), buf) + } } -} -impl Value for &[u8] { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - let val_len: i32 = self.len().try_into().map_err(|_| ValueTooBig)?; - buf.put_i32(val_len); + impl Value for &[u8] { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + let val_len: i32 = self.len().try_into().map_err(|_| ValueTooBig)?; + buf.put_i32(val_len); - buf.extend_from_slice(self); + buf.extend_from_slice(self); - Ok(()) + Ok(()) + } } -} -impl Value for [u8; N] { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - let val_len: i32 = self.len().try_into().map_err(|_| ValueTooBig)?; - buf.put_i32(val_len); + impl Value for [u8; N] { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + let val_len: i32 = self.len().try_into().map_err(|_| ValueTooBig)?; + buf.put_i32(val_len); - buf.extend_from_slice(self); + buf.extend_from_slice(self); - Ok(()) + Ok(()) + } } -} -impl Value for IpAddr { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - match self { - IpAddr::V4(addr) => { - buf.put_i32(4); - buf.extend_from_slice(&addr.octets()); - } - IpAddr::V6(addr) => { - buf.put_i32(16); - buf.extend_from_slice(&addr.octets()); + impl Value for IpAddr { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + match self { + IpAddr::V4(addr) => { + buf.put_i32(4); + buf.extend_from_slice(&addr.octets()); + } + IpAddr::V6(addr) => { + buf.put_i32(16); + buf.extend_from_slice(&addr.octets()); + } } - } - Ok(()) + Ok(()) + } } -} -impl Value for String { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - <&str as Value>::serialize(&self.as_str(), buf) + impl Value for String { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + <&str as Value>::serialize(&self.as_str(), buf) + } } -} -/// Every `Option` can be serialized as None -> NULL, Some(val) -> val.serialize() -impl Value for Option { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - match self { - Some(val) => ::serialize(val, buf), - None => { - buf.put_i32(-1); - Ok(()) + /// Every `Option` can be serialized as None -> NULL, Some(val) -> val.serialize() + impl Value for Option { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + match self { + Some(val) => ::serialize(val, buf), + None => { + buf.put_i32(-1); + Ok(()) + } } } } -} -impl Value for Unset { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - // Unset serializes itself to empty value with length = -2 - buf.put_i32(-2); - Ok(()) + impl Value for Unset { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + // Unset serializes itself to empty value with length = -2 + buf.put_i32(-2); + Ok(()) + } } -} -impl Value for Counter { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - self.0.serialize(buf) + impl Value for Counter { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + self.0.serialize(buf) + } } -} -impl Value for CqlDuration { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - let bytes_num_pos: usize = buf.len(); - buf.put_i32(0); + impl Value for CqlDuration { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + let bytes_num_pos: usize = buf.len(); + buf.put_i32(0); - vint_encode(self.months as i64, buf); - vint_encode(self.days as i64, buf); - vint_encode(self.nanoseconds, buf); + vint_encode(self.months as i64, buf); + vint_encode(self.days as i64, buf); + vint_encode(self.nanoseconds, buf); - let written_bytes: usize = buf.len() - bytes_num_pos - 4; - let written_bytes_i32: i32 = written_bytes.try_into().map_err(|_| ValueTooBig)?; - buf[bytes_num_pos..(bytes_num_pos + 4)].copy_from_slice(&written_bytes_i32.to_be_bytes()); + let written_bytes: usize = buf.len() - bytes_num_pos - 4; + let written_bytes_i32: i32 = written_bytes.try_into().map_err(|_| ValueTooBig)?; + buf[bytes_num_pos..(bytes_num_pos + 4)] + .copy_from_slice(&written_bytes_i32.to_be_bytes()); - Ok(()) - } -} - -impl Value for MaybeUnset { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - match self { - MaybeUnset::Set(v) => v.serialize(buf), - MaybeUnset::Unset => Unset.serialize(buf), + Ok(()) } } -} -// Every &impl Value and &dyn Value should also implement Value -impl Value for &T { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - ::serialize(*self, buf) + impl Value for MaybeUnset { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + match self { + MaybeUnset::Set(v) => v.serialize(buf), + MaybeUnset::Unset => Unset.serialize(buf), + } + } } -} -// Every Boxed Value should also implement Value -impl Value for Box { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - ::serialize(self.as_ref(), buf) + // Every &impl Value and &dyn Value should also implement Value + impl Value for &T { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + ::serialize(*self, buf) + } } -} - -fn serialize_map( - kv_iter: impl Iterator, - kv_count: usize, - buf: &mut Vec, -) -> Result<(), ValueTooBig> { - let bytes_num_pos: usize = buf.len(); - buf.put_i32(0); - buf.put_i32(kv_count.try_into().map_err(|_| ValueTooBig)?); - for (key, value) in kv_iter { - ::serialize(&key, buf)?; - ::serialize(&value, buf)?; + // Every Boxed Value should also implement Value + impl Value for Box { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + ::serialize(self.as_ref(), buf) + } } - let written_bytes: usize = buf.len() - bytes_num_pos - 4; - let written_bytes_i32: i32 = written_bytes.try_into().map_err(|_| ValueTooBig)?; - buf[bytes_num_pos..(bytes_num_pos + 4)].copy_from_slice(&written_bytes_i32.to_be_bytes()); + fn serialize_map( + kv_iter: impl Iterator, + kv_count: usize, + buf: &mut Vec, + ) -> Result<(), ValueTooBig> { + let bytes_num_pos: usize = buf.len(); + buf.put_i32(0); - Ok(()) -} + buf.put_i32(kv_count.try_into().map_err(|_| ValueTooBig)?); + for (key, value) in kv_iter { + ::serialize(&key, buf)?; + ::serialize(&value, buf)?; + } -fn serialize_list_or_set<'a, V: 'a + Value>( - elements_iter: impl Iterator, - element_count: usize, - buf: &mut Vec, -) -> Result<(), ValueTooBig> { - let bytes_num_pos: usize = buf.len(); - buf.put_i32(0); + let written_bytes: usize = buf.len() - bytes_num_pos - 4; + let written_bytes_i32: i32 = written_bytes.try_into().map_err(|_| ValueTooBig)?; + buf[bytes_num_pos..(bytes_num_pos + 4)].copy_from_slice(&written_bytes_i32.to_be_bytes()); - buf.put_i32(element_count.try_into().map_err(|_| ValueTooBig)?); - for value in elements_iter { - ::serialize(value, buf)?; + Ok(()) } - let written_bytes: usize = buf.len() - bytes_num_pos - 4; - let written_bytes_i32: i32 = written_bytes.try_into().map_err(|_| ValueTooBig)?; - buf[bytes_num_pos..(bytes_num_pos + 4)].copy_from_slice(&written_bytes_i32.to_be_bytes()); + fn serialize_list_or_set<'a, V: 'a + Value>( + elements_iter: impl Iterator, + element_count: usize, + buf: &mut Vec, + ) -> Result<(), ValueTooBig> { + let bytes_num_pos: usize = buf.len(); + buf.put_i32(0); - Ok(()) -} + buf.put_i32(element_count.try_into().map_err(|_| ValueTooBig)?); + for value in elements_iter { + ::serialize(value, buf)?; + } -impl Value for HashSet { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - serialize_list_or_set(self.iter(), self.len(), buf) - } -} + let written_bytes: usize = buf.len() - bytes_num_pos - 4; + let written_bytes_i32: i32 = written_bytes.try_into().map_err(|_| ValueTooBig)?; + buf[bytes_num_pos..(bytes_num_pos + 4)].copy_from_slice(&written_bytes_i32.to_be_bytes()); -impl Value for HashMap { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - serialize_map(self.iter(), self.len(), buf) + Ok(()) } -} -impl Value for BTreeSet { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - serialize_list_or_set(self.iter(), self.len(), buf) + impl Value for HashSet { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + serialize_list_or_set(self.iter(), self.len(), buf) + } } -} -impl Value for BTreeMap { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - serialize_map(self.iter(), self.len(), buf) + impl Value for HashMap { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + serialize_map(self.iter(), self.len(), buf) + } } -} -impl Value for Vec { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - serialize_list_or_set(self.iter(), self.len(), buf) + impl Value for BTreeSet { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + serialize_list_or_set(self.iter(), self.len(), buf) + } } -} -impl Value for &[T] { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - serialize_list_or_set(self.iter(), self.len(), buf) + impl Value for BTreeMap { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + serialize_map(self.iter(), self.len(), buf) + } } -} - -fn serialize_tuple( - elem_iter: impl Iterator, - buf: &mut Vec, -) -> Result<(), ValueTooBig> { - let bytes_num_pos: usize = buf.len(); - buf.put_i32(0); - for elem in elem_iter { - elem.serialize(buf)?; + impl Value for Vec { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + serialize_list_or_set(self.iter(), self.len(), buf) + } } - let written_bytes: usize = buf.len() - bytes_num_pos - 4; - let written_bytes_i32: i32 = written_bytes.try_into().map_err(|_| ValueTooBig)?; - buf[bytes_num_pos..(bytes_num_pos + 4)].copy_from_slice(&written_bytes_i32.to_be_bytes()); + impl Value for &[T] { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + serialize_list_or_set(self.iter(), self.len(), buf) + } + } - Ok(()) -} + fn serialize_tuple( + elem_iter: impl Iterator, + buf: &mut Vec, + ) -> Result<(), ValueTooBig> { + let bytes_num_pos: usize = buf.len(); + buf.put_i32(0); -fn serialize_empty(buf: &mut Vec) -> Result<(), ValueTooBig> { - buf.put_i32(0); - Ok(()) -} + for elem in elem_iter { + elem.serialize(buf)?; + } -impl Value for CqlValue { - fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { - match self { - CqlValue::Map(m) => serialize_map(m.iter().map(|p| (&p.0, &p.1)), m.len(), buf), - CqlValue::Tuple(t) => serialize_tuple(t.iter(), buf), + let written_bytes: usize = buf.len() - bytes_num_pos - 4; + let written_bytes_i32: i32 = written_bytes.try_into().map_err(|_| ValueTooBig)?; + buf[bytes_num_pos..(bytes_num_pos + 4)].copy_from_slice(&written_bytes_i32.to_be_bytes()); - // A UDT value is composed of successive [bytes] values, one for each field of the UDT - // value (in the order defined by the type), so they serialize in a same way tuples do. - CqlValue::UserDefinedType { fields, .. } => { - serialize_tuple(fields.iter().map(|(_, value)| value), buf) - } + Ok(()) + } - CqlValue::Date(d) => d.serialize(buf), - CqlValue::Duration(d) => d.serialize(buf), - CqlValue::Timestamp(t) => t.serialize(buf), - CqlValue::Time(t) => t.serialize(buf), + fn serialize_empty(buf: &mut Vec) -> Result<(), ValueTooBig> { + buf.put_i32(0); + Ok(()) + } - CqlValue::Ascii(s) | CqlValue::Text(s) => s.serialize(buf), - CqlValue::List(v) | CqlValue::Set(v) => v.serialize(buf), + impl Value for CqlValue { + fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { + match self { + CqlValue::Map(m) => serialize_map(m.iter().map(|p| (&p.0, &p.1)), m.len(), buf), + CqlValue::Tuple(t) => serialize_tuple(t.iter(), buf), - CqlValue::Blob(b) => b.serialize(buf), - CqlValue::Boolean(b) => b.serialize(buf), - CqlValue::Counter(c) => c.serialize(buf), - CqlValue::Decimal(d) => d.serialize(buf), - CqlValue::Double(d) => d.serialize(buf), - CqlValue::Float(f) => f.serialize(buf), - CqlValue::Int(i) => i.serialize(buf), - CqlValue::BigInt(i) => i.serialize(buf), - CqlValue::Inet(i) => i.serialize(buf), - CqlValue::SmallInt(s) => s.serialize(buf), - CqlValue::TinyInt(t) => t.serialize(buf), - CqlValue::Timeuuid(t) => t.serialize(buf), - CqlValue::Uuid(u) => u.serialize(buf), - CqlValue::Varint(v) => v.serialize(buf), + // A UDT value is composed of successive [bytes] values, one for each field of the UDT + // value (in the order defined by the type), so they serialize in a same way tuples do. + CqlValue::UserDefinedType { fields, .. } => { + serialize_tuple(fields.iter().map(|(_, value)| value), buf) + } - CqlValue::Empty => serialize_empty(buf), + CqlValue::Date(d) => d.serialize(buf), + CqlValue::Duration(d) => d.serialize(buf), + CqlValue::Timestamp(t) => t.serialize(buf), + CqlValue::Time(t) => t.serialize(buf), + + CqlValue::Ascii(s) | CqlValue::Text(s) => s.serialize(buf), + CqlValue::List(v) | CqlValue::Set(v) => v.serialize(buf), + + CqlValue::Blob(b) => b.serialize(buf), + CqlValue::Boolean(b) => b.serialize(buf), + CqlValue::Counter(c) => c.serialize(buf), + CqlValue::Decimal(d) => d.serialize(buf), + CqlValue::Double(d) => d.serialize(buf), + CqlValue::Float(f) => f.serialize(buf), + CqlValue::Int(i) => i.serialize(buf), + CqlValue::BigInt(i) => i.serialize(buf), + CqlValue::Inet(i) => i.serialize(buf), + CqlValue::SmallInt(s) => s.serialize(buf), + CqlValue::TinyInt(t) => t.serialize(buf), + CqlValue::Timeuuid(t) => t.serialize(buf), + CqlValue::Uuid(u) => u.serialize(buf), + CqlValue::Varint(v) => v.serialize(buf), + + CqlValue::Empty => serialize_empty(buf), + } } } -} -macro_rules! impl_value_for_tuple { + macro_rules! impl_value_for_tuple { ( $($Ti:ident),* ; $($FieldI:tt),* ) => { impl<$($Ti),+> Value for ($($Ti,)+) where @@ -1437,126 +1548,126 @@ macro_rules! impl_value_for_tuple { } } -impl_value_for_tuple!(T0; 0); -impl_value_for_tuple!(T0, T1; 0, 1); -impl_value_for_tuple!(T0, T1, T2; 0, 1, 2); -impl_value_for_tuple!(T0, T1, T2, T3; 0, 1, 2, 3); -impl_value_for_tuple!(T0, T1, T2, T3, T4; 0, 1, 2, 3, 4); -impl_value_for_tuple!(T0, T1, T2, T3, T4, T5; 0, 1, 2, 3, 4, 5); -impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6; 0, 1, 2, 3, 4, 5, 6); -impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7; 0, 1, 2, 3, 4, 5, 6, 7); -impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8; 0, 1, 2, 3, 4, 5, 6, 7, 8); -impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9; + impl_value_for_tuple!(T0; 0); + impl_value_for_tuple!(T0, T1; 0, 1); + impl_value_for_tuple!(T0, T1, T2; 0, 1, 2); + impl_value_for_tuple!(T0, T1, T2, T3; 0, 1, 2, 3); + impl_value_for_tuple!(T0, T1, T2, T3, T4; 0, 1, 2, 3, 4); + impl_value_for_tuple!(T0, T1, T2, T3, T4, T5; 0, 1, 2, 3, 4, 5); + impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6; 0, 1, 2, 3, 4, 5, 6); + impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7; 0, 1, 2, 3, 4, 5, 6, 7); + impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8; 0, 1, 2, 3, 4, 5, 6, 7, 8); + impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9); -impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10; + impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); -impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11; + impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); -impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12; + impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12); -impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13; + impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13); -impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14; + impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14); -impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15; + impl_value_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); -// -// ValueList impls -// + // + // ValueList impls + // -// Implement ValueList for the unit type -impl ValueList for () { - fn serialized(&self) -> SerializedResult<'_> { - Ok(Cow::Owned(LegacySerializedValues::new())) + // Implement ValueList for the unit type + impl ValueList for () { + fn serialized(&self) -> SerializedResult<'_> { + Ok(Cow::Owned(LegacySerializedValues::new())) + } } -} -// Implement ValueList for &[] - u8 because otherwise rust can't infer type -impl ValueList for [u8; 0] { - fn serialized(&self) -> SerializedResult<'_> { - Ok(Cow::Owned(LegacySerializedValues::new())) + // Implement ValueList for &[] - u8 because otherwise rust can't infer type + impl ValueList for [u8; 0] { + fn serialized(&self) -> SerializedResult<'_> { + Ok(Cow::Owned(LegacySerializedValues::new())) + } } -} -// Implement ValueList for slices of Value types -impl ValueList for &[T] { - fn serialized(&self) -> SerializedResult<'_> { - let size = std::mem::size_of_val(*self); - let mut result = LegacySerializedValues::with_capacity(size); - for val in *self { - result.add_value(val)?; - } + // Implement ValueList for slices of Value types + impl ValueList for &[T] { + fn serialized(&self) -> SerializedResult<'_> { + let size = std::mem::size_of_val(*self); + let mut result = LegacySerializedValues::with_capacity(size); + for val in *self { + result.add_value(val)?; + } - Ok(Cow::Owned(result)) + Ok(Cow::Owned(result)) + } } -} -// Implement ValueList for Vec -impl ValueList for Vec { - fn serialized(&self) -> SerializedResult<'_> { - let slice = self.as_slice(); - let size = std::mem::size_of_val(slice); - let mut result = LegacySerializedValues::with_capacity(size); - for val in self { - result.add_value(val)?; - } + // Implement ValueList for Vec + impl ValueList for Vec { + fn serialized(&self) -> SerializedResult<'_> { + let slice = self.as_slice(); + let size = std::mem::size_of_val(slice); + let mut result = LegacySerializedValues::with_capacity(size); + for val in self { + result.add_value(val)?; + } - Ok(Cow::Owned(result)) + Ok(Cow::Owned(result)) + } } -} -// Implement ValueList for maps, which serializes named values -macro_rules! impl_value_list_for_btree_map { - ($key_type:ty) => { - impl ValueList for BTreeMap<$key_type, T> { - fn serialized(&self) -> SerializedResult<'_> { - let mut result = LegacySerializedValues::with_capacity(self.len()); - for (key, val) in self { - result.add_named_value(key, val)?; - } + // Implement ValueList for maps, which serializes named values + macro_rules! impl_value_list_for_btree_map { + ($key_type:ty) => { + impl ValueList for BTreeMap<$key_type, T> { + fn serialized(&self) -> SerializedResult<'_> { + let mut result = LegacySerializedValues::with_capacity(self.len()); + for (key, val) in self { + result.add_named_value(key, val)?; + } - Ok(Cow::Owned(result)) + Ok(Cow::Owned(result)) + } } - } - }; -} + }; + } -// Implement ValueList for maps, which serializes named values -macro_rules! impl_value_list_for_hash_map { - ($key_type:ty) => { - impl ValueList for HashMap<$key_type, T, S> { - fn serialized(&self) -> SerializedResult<'_> { - let mut result = LegacySerializedValues::with_capacity(self.len()); - for (key, val) in self { - result.add_named_value(key, val)?; - } + // Implement ValueList for maps, which serializes named values + macro_rules! impl_value_list_for_hash_map { + ($key_type:ty) => { + impl ValueList for HashMap<$key_type, T, S> { + fn serialized(&self) -> SerializedResult<'_> { + let mut result = LegacySerializedValues::with_capacity(self.len()); + for (key, val) in self { + result.add_named_value(key, val)?; + } - Ok(Cow::Owned(result)) + Ok(Cow::Owned(result)) + } } - } - }; -} + }; + } -impl_value_list_for_hash_map!(String); -impl_value_list_for_hash_map!(&str); -impl_value_list_for_btree_map!(String); -impl_value_list_for_btree_map!(&str); + impl_value_list_for_hash_map!(String); + impl_value_list_for_hash_map!(&str); + impl_value_list_for_btree_map!(String); + impl_value_list_for_btree_map!(&str); -// Implement ValueList for tuples of Values of size up to 16 + // Implement ValueList for tuples of Values of size up to 16 -// Here is an example implementation for (T0, ) -// Further variants are done using a macro -impl ValueList for (T0,) { - fn serialized(&self) -> SerializedResult<'_> { - let size = std::mem::size_of_val(self); - let mut result = LegacySerializedValues::with_capacity(size); - result.add_value(&self.0)?; - Ok(Cow::Owned(result)) + // Here is an example implementation for (T0, ) + // Further variants are done using a macro + impl ValueList for (T0,) { + fn serialized(&self) -> SerializedResult<'_> { + let size = std::mem::size_of_val(self); + let mut result = LegacySerializedValues::with_capacity(size); + result.add_value(&self.0)?; + Ok(Cow::Owned(result)) + } } -} -macro_rules! impl_value_list_for_tuple { + macro_rules! impl_value_list_for_tuple { ( $($Ti:ident),* ; $($FieldI:tt),*) => { impl<$($Ti),+> ValueList for ($($Ti,)+) where @@ -1574,143 +1685,151 @@ macro_rules! impl_value_list_for_tuple { } } -impl_value_list_for_tuple!(T0, T1; 0, 1); -impl_value_list_for_tuple!(T0, T1, T2; 0, 1, 2); -impl_value_list_for_tuple!(T0, T1, T2, T3; 0, 1, 2, 3); -impl_value_list_for_tuple!(T0, T1, T2, T3, T4; 0, 1, 2, 3, 4); -impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5; 0, 1, 2, 3, 4, 5); -impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6; 0, 1, 2, 3, 4, 5, 6); -impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7; 0, 1, 2, 3, 4, 5, 6, 7); -impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8; 0, 1, 2, 3, 4, 5, 6, 7, 8); -impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9); -impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10; + impl_value_list_for_tuple!(T0, T1; 0, 1); + impl_value_list_for_tuple!(T0, T1, T2; 0, 1, 2); + impl_value_list_for_tuple!(T0, T1, T2, T3; 0, 1, 2, 3); + impl_value_list_for_tuple!(T0, T1, T2, T3, T4; 0, 1, 2, 3, 4); + impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5; 0, 1, 2, 3, 4, 5); + impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6; 0, 1, 2, 3, 4, 5, 6); + impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7; 0, 1, 2, 3, 4, 5, 6, 7); + impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8; 0, 1, 2, 3, 4, 5, 6, 7, 8); + impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); -impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11; + impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); -impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12; + impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12); -impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13; + impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13); -impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14; + impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14); -impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15; + impl_value_list_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); -// Every &impl ValueList should also implement ValueList -impl ValueList for &T { - fn serialized(&self) -> SerializedResult<'_> { - ::serialized(*self) + // Every &impl ValueList should also implement ValueList + impl ValueList for &T { + fn serialized(&self) -> SerializedResult<'_> { + ::serialized(*self) + } } -} -impl ValueList for LegacySerializedValues { - fn serialized(&self) -> SerializedResult<'_> { - Ok(Cow::Borrowed(self)) + impl ValueList for LegacySerializedValues { + fn serialized(&self) -> SerializedResult<'_> { + Ok(Cow::Borrowed(self)) + } } -} -impl ValueList for Cow<'_, LegacySerializedValues> { - fn serialized(&self) -> SerializedResult<'_> { - Ok(Cow::Borrowed(self.as_ref())) + impl ValueList for Cow<'_, LegacySerializedValues> { + fn serialized(&self) -> SerializedResult<'_> { + Ok(Cow::Borrowed(self.as_ref())) + } } -} - -// -// BatchValues impls -// -/// Implements `BatchValues` from an `Iterator` over references to things that implement `ValueList` -/// -/// This is to avoid requiring allocating a new `Vec` containing all the `ValueList`s directly: -/// with this, one can write: -/// `session.batch(&batch, BatchValuesFromIterator::from(lines_to_insert.iter().map(|l| &l.value_list)))` -/// where `lines_to_insert` may also contain e.g. data to pick the statement... -/// -/// The underlying iterator will always be cloned at least once, once to compute the length if it can't be known -/// in advance, and be re-cloned at every retry. -/// It is consequently expected that the provided iterator is cheap to clone (e.g. `slice.iter().map(...)`). -pub struct LegacyBatchValuesFromIter<'a, IT> { - it: IT, - _spooky: std::marker::PhantomData<&'a ()>, -} + // + // BatchValues impls + // -impl<'a, IT, VL> LegacyBatchValuesFromIter<'a, IT> -where - IT: Iterator + Clone, - VL: ValueList + 'a, -{ - pub fn new(into_iter: impl IntoIterator) -> Self { - Self { - it: into_iter.into_iter(), - _spooky: std::marker::PhantomData, + /// Implements `BatchValues` from an `Iterator` over references to things that implement `ValueList` + /// + /// This is to avoid requiring allocating a new `Vec` containing all the `ValueList`s directly: + /// with this, one can write: + /// `session.batch(&batch, BatchValuesFromIterator::from(lines_to_insert.iter().map(|l| &l.value_list)))` + /// where `lines_to_insert` may also contain e.g. data to pick the statement... + /// + /// The underlying iterator will always be cloned at least once, once to compute the length if it can't be known + /// in advance, and be re-cloned at every retry. + /// It is consequently expected that the provided iterator is cheap to clone (e.g. `slice.iter().map(...)`). + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub struct LegacyBatchValuesFromIter<'a, IT> { + it: IT, + _spooky: std::marker::PhantomData<&'a ()>, + } + + impl<'a, IT, VL> LegacyBatchValuesFromIter<'a, IT> + where + IT: Iterator + Clone, + VL: ValueList + 'a, + { + pub fn new(into_iter: impl IntoIterator) -> Self { + Self { + it: into_iter.into_iter(), + _spooky: std::marker::PhantomData, + } } } -} -impl<'a, IT, VL> From for LegacyBatchValuesFromIter<'a, IT> -where - IT: Iterator + Clone, - VL: ValueList + 'a, -{ - fn from(it: IT) -> Self { - Self::new(it) + impl<'a, IT, VL> From for LegacyBatchValuesFromIter<'a, IT> + where + IT: Iterator + Clone, + VL: ValueList + 'a, + { + fn from(it: IT) -> Self { + Self::new(it) + } } -} -impl<'a, IT, VL> LegacyBatchValues for LegacyBatchValuesFromIter<'a, IT> -where - IT: Iterator + Clone, - VL: ValueList + 'a, -{ - type LegacyBatchValuesIter<'r> - = LegacyBatchValuesIteratorFromIterator + impl<'a, IT, VL> LegacyBatchValues for LegacyBatchValuesFromIter<'a, IT> where - Self: 'r; - fn batch_values_iter(&self) -> Self::LegacyBatchValuesIter<'_> { - self.it.clone().into() + IT: Iterator + Clone, + VL: ValueList + 'a, + { + type LegacyBatchValuesIter<'r> + = LegacyBatchValuesIteratorFromIterator + where + Self: 'r; + fn batch_values_iter(&self) -> Self::LegacyBatchValuesIter<'_> { + self.it.clone().into() + } } -} -// Implement BatchValues for slices of ValueList types -impl LegacyBatchValues for [T] { - type LegacyBatchValuesIter<'r> - = LegacyBatchValuesIteratorFromIterator> - where - Self: 'r; - fn batch_values_iter(&self) -> Self::LegacyBatchValuesIter<'_> { - self.iter().into() + // Implement BatchValues for slices of ValueList types + impl LegacyBatchValues for [T] { + type LegacyBatchValuesIter<'r> + = LegacyBatchValuesIteratorFromIterator> + where + Self: 'r; + fn batch_values_iter(&self) -> Self::LegacyBatchValuesIter<'_> { + self.iter().into() + } } -} -// Implement BatchValues for Vec -impl LegacyBatchValues for Vec { - type LegacyBatchValuesIter<'r> - = LegacyBatchValuesIteratorFromIterator> - where - Self: 'r; - fn batch_values_iter(&self) -> Self::LegacyBatchValuesIter<'_> { - LegacyBatchValues::batch_values_iter(self.as_slice()) + // Implement BatchValues for Vec + impl LegacyBatchValues for Vec { + type LegacyBatchValuesIter<'r> + = LegacyBatchValuesIteratorFromIterator> + where + Self: 'r; + fn batch_values_iter(&self) -> Self::LegacyBatchValuesIter<'_> { + LegacyBatchValues::batch_values_iter(self.as_slice()) + } } -} -// Here is an example implementation for (T0, ) -// Further variants are done using a macro -impl LegacyBatchValues for (T0,) { - type LegacyBatchValuesIter<'r> - = LegacyBatchValuesIteratorFromIterator> - where - Self: 'r; - fn batch_values_iter(&self) -> Self::LegacyBatchValuesIter<'_> { - std::iter::once(&self.0).into() + // Here is an example implementation for (T0, ) + // Further variants are done using a macro + impl LegacyBatchValues for (T0,) { + type LegacyBatchValuesIter<'r> + = LegacyBatchValuesIteratorFromIterator> + where + Self: 'r; + fn batch_values_iter(&self) -> Self::LegacyBatchValuesIter<'_> { + std::iter::once(&self.0).into() + } } -} -pub struct TupleValuesIter<'a, T> { - tuple: &'a T, - idx: usize, -} + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub struct TupleValuesIter<'a, T> { + tuple: &'a T, + idx: usize, + } -macro_rules! impl_batch_values_for_tuple { + macro_rules! impl_batch_values_for_tuple { ( $($Ti:ident),* ; $($FieldI:tt),* ; $TupleSize:tt) => { impl<$($Ti),+> LegacyBatchValues for ($($Ti,)+) where @@ -1763,103 +1882,117 @@ macro_rules! impl_batch_values_for_tuple { } } -impl_batch_values_for_tuple!(T0, T1; 0, 1; 2); -impl_batch_values_for_tuple!(T0, T1, T2; 0, 1, 2; 3); -impl_batch_values_for_tuple!(T0, T1, T2, T3; 0, 1, 2, 3; 4); -impl_batch_values_for_tuple!(T0, T1, T2, T3, T4; 0, 1, 2, 3, 4; 5); -impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5; 0, 1, 2, 3, 4, 5; 6); -impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6; 0, 1, 2, 3, 4, 5, 6; 7); -impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7; 0, 1, 2, 3, 4, 5, 6, 7; 8); -impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8; 0, 1, 2, 3, 4, 5, 6, 7, 8; 9); -impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9; + impl_batch_values_for_tuple!(T0, T1; 0, 1; 2); + impl_batch_values_for_tuple!(T0, T1, T2; 0, 1, 2; 3); + impl_batch_values_for_tuple!(T0, T1, T2, T3; 0, 1, 2, 3; 4); + impl_batch_values_for_tuple!(T0, T1, T2, T3, T4; 0, 1, 2, 3, 4; 5); + impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5; 0, 1, 2, 3, 4, 5; 6); + impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6; 0, 1, 2, 3, 4, 5, 6; 7); + impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7; 0, 1, 2, 3, 4, 5, 6, 7; 8); + impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8; 0, 1, 2, 3, 4, 5, 6, 7, 8; 9); + impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9; 10); -impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10; + impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10; 11); -impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11; + impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11; 12); -impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12; + impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12; 13); -impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13; + impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13; 14); -impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14; + impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14; 15); -impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15; + impl_batch_values_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15; 16); -// Every &impl BatchValues should also implement BatchValues -impl LegacyBatchValues for &T { - type LegacyBatchValuesIter<'r> - = ::LegacyBatchValuesIter<'r> - where - Self: 'r; - fn batch_values_iter(&self) -> Self::LegacyBatchValuesIter<'_> { - ::batch_values_iter(*self) + // Every &impl BatchValues should also implement BatchValues + impl LegacyBatchValues for &T { + type LegacyBatchValuesIter<'r> + = ::LegacyBatchValuesIter<'r> + where + Self: 'r; + fn batch_values_iter(&self) -> Self::LegacyBatchValuesIter<'_> { + ::batch_values_iter(*self) + } } -} - -/// Allows reusing already-serialized first value -/// -/// We'll need to build a `LegacySerializedValues` for the first ~`ValueList` of a batch to figure out the shard (#448). -/// Once that is done, we can use that instead of re-serializing. -/// -/// This struct implements both `BatchValues` and `BatchValuesIterator` for that purpose -pub struct LegacyBatchValuesFirstSerialized<'f, T> { - first: Option<&'f LegacySerializedValues>, - rest: T, -} -impl<'f, T: LegacyBatchValues> LegacyBatchValuesFirstSerialized<'f, T> { - pub fn new( - batch_values: T, - already_serialized_first: Option<&'f LegacySerializedValues>, - ) -> Self { - Self { - first: already_serialized_first, - rest: batch_values, + /// Allows reusing already-serialized first value + /// + /// We'll need to build a `LegacySerializedValues` for the first ~`ValueList` of a batch to figure out the shard (#448). + /// Once that is done, we can use that instead of re-serializing. + /// + /// This struct implements both `BatchValues` and `BatchValuesIterator` for that purpose + #[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" + )] + pub struct LegacyBatchValuesFirstSerialized<'f, T> { + first: Option<&'f LegacySerializedValues>, + rest: T, + } + + impl<'f, T: LegacyBatchValues> LegacyBatchValuesFirstSerialized<'f, T> { + pub fn new( + batch_values: T, + already_serialized_first: Option<&'f LegacySerializedValues>, + ) -> Self { + Self { + first: already_serialized_first, + rest: batch_values, + } } } -} -impl<'f, BV: LegacyBatchValues> LegacyBatchValues for LegacyBatchValuesFirstSerialized<'f, BV> { - type LegacyBatchValuesIter<'r> - = LegacyBatchValuesFirstSerialized<'f, ::LegacyBatchValuesIter<'r>> - where - Self: 'r; - fn batch_values_iter(&self) -> Self::LegacyBatchValuesIter<'_> { - LegacyBatchValuesFirstSerialized { - first: self.first, - rest: self.rest.batch_values_iter(), + impl<'f, BV: LegacyBatchValues> LegacyBatchValues for LegacyBatchValuesFirstSerialized<'f, BV> { + type LegacyBatchValuesIter<'r> + = LegacyBatchValuesFirstSerialized< + 'f, + ::LegacyBatchValuesIter<'r>, + > + where + Self: 'r; + fn batch_values_iter(&self) -> Self::LegacyBatchValuesIter<'_> { + LegacyBatchValuesFirstSerialized { + first: self.first, + rest: self.rest.batch_values_iter(), + } } } -} -impl<'a, 'f: 'a, IT: LegacyBatchValuesIterator<'a>> LegacyBatchValuesIterator<'a> - for LegacyBatchValuesFirstSerialized<'f, IT> -{ - fn next_serialized(&mut self) -> Option> { - match self.first.take() { - Some(first) => { - self.rest.skip_next(); - Some(Ok(Cow::Borrowed(first))) + impl<'a, 'f: 'a, IT: LegacyBatchValuesIterator<'a>> LegacyBatchValuesIterator<'a> + for LegacyBatchValuesFirstSerialized<'f, IT> + { + fn next_serialized(&mut self) -> Option> { + match self.first.take() { + Some(first) => { + self.rest.skip_next(); + Some(Ok(Cow::Borrowed(first))) + } + None => self.rest.next_serialized(), } - None => self.rest.next_serialized(), - } - } - fn write_next_to_request( - &mut self, - buf: &mut impl BufMut, - ) -> Option> { - match self.first.take() { - Some(first) => { - self.rest.skip_next(); - first.write_to_request(buf); - Some(Ok(())) + } + fn write_next_to_request( + &mut self, + buf: &mut impl BufMut, + ) -> Option> { + match self.first.take() { + Some(first) => { + self.rest.skip_next(); + first.write_to_request(buf); + Some(Ok(())) + } + None => self.rest.write_next_to_request(buf), } - None => self.rest.write_next_to_request(buf), } - } - fn skip_next(&mut self) -> Option<()> { - self.rest.skip_next(); - self.first.take().map(|_| ()) + fn skip_next(&mut self) -> Option<()> { + self.rest.skip_next(); + self.first.take().map(|_| ()) + } } } +#[allow(deprecated)] +pub use legacy::{ + LegacyBatchValues, LegacyBatchValuesFirstSerialized, LegacyBatchValuesFromIter, + LegacyBatchValuesIterator, LegacyBatchValuesIteratorFromIterator, LegacySerializedValues, + LegacySerializedValuesIterator, SerializedResult, TupleValuesIter, Value, ValueList, +}; diff --git a/scylla-cql/src/frame/value_tests.rs b/scylla-cql/src/frame/value_tests.rs index 62d998cbf..a2df53a4d 100644 --- a/scylla-cql/src/frame/value_tests.rs +++ b/scylla-cql/src/frame/value_tests.rs @@ -1,3 +1,6 @@ +// TODO: remove this once deprecated items are deleted. +#![allow(deprecated)] + use crate::frame::value::{CqlTimeuuid, CqlVarint}; use crate::frame::{response::result::CqlValue, types::RawValue, value::LegacyBatchValuesIterator}; use crate::types::serialize::batch::{BatchValues, BatchValuesIterator, LegacyBatchValuesAdapter}; diff --git a/scylla-cql/src/lib.rs b/scylla-cql/src/lib.rs index 228fc43f8..09a4e56d7 100644 --- a/scylla-cql/src/lib.rs +++ b/scylla-cql/src/lib.rs @@ -16,7 +16,9 @@ pub mod macros { #[allow(deprecated)] pub use crate::impl_from_cql_value_from_method; + #[allow(deprecated)] pub use crate::impl_serialize_row_via_value_list; + #[allow(deprecated)] pub use crate::impl_serialize_value_via_value; } @@ -35,6 +37,7 @@ pub mod _macro_internal { FromCqlVal, FromCqlValError, FromRow, FromRowError, }; pub use crate::frame::response::result::{ColumnSpec, ColumnType, CqlValue, Row}; + #[allow(deprecated)] pub use crate::frame::value::{ LegacySerializedValues, SerializedResult, Value, ValueList, ValueTooBig, }; diff --git a/scylla-cql/src/types/serialize/batch.rs b/scylla-cql/src/types/serialize/batch.rs index cca0ec1b0..aff43b990 100644 --- a/scylla-cql/src/types/serialize/batch.rs +++ b/scylla-cql/src/types/serialize/batch.rs @@ -4,6 +4,7 @@ // Note: When editing above doc-comment edit the corresponding comment on // re-export module in scylla crate too. +#[allow(deprecated)] use crate::frame::value::{LegacyBatchValues, LegacyBatchValuesIterator}; use super::row::{RowSerializationContext, SerializeRow}; @@ -332,8 +333,13 @@ impl BatchValues for &T { /// Note that the [`LegacyBatchValues`] trait is deprecated and will be /// removed in the future, and you should prefer using [`BatchValues`] as it is /// more type-safe. +#[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" +)] pub struct LegacyBatchValuesAdapter(pub T); +#[allow(deprecated)] impl BatchValues for LegacyBatchValuesAdapter where T: LegacyBatchValues, @@ -351,8 +357,13 @@ where /// A newtype wrapper which adjusts an existing types that implement /// [`LegacyBatchValuesIterator`] to the current [`BatchValuesIterator`] API. +#[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" +)] pub struct LegacyBatchValuesIteratorAdapter(pub T); +#[allow(deprecated)] impl<'r, T> BatchValuesIterator<'r> for LegacyBatchValuesIteratorAdapter where T: LegacyBatchValuesIterator<'r>, diff --git a/scylla-cql/src/types/serialize/row.rs b/scylla-cql/src/types/serialize/row.rs index 665335ebe..7478a0b9c 100644 --- a/scylla-cql/src/types/serialize/row.rs +++ b/scylla-cql/src/types/serialize/row.rs @@ -16,8 +16,8 @@ use crate::frame::request::RequestDeserializationError; use crate::frame::response::result::ColumnType; use crate::frame::response::result::PreparedMetadata; use crate::frame::types; -use crate::frame::value::SerializeValuesError; -use crate::frame::value::{LegacySerializedValues, ValueList}; +#[allow(deprecated)] +use crate::frame::value::{LegacySerializedValues, SerializeValuesError, ValueList}; use crate::frame::{response::result::ColumnSpec, types::RawValue}; use super::value::SerializeValue; @@ -282,10 +282,12 @@ impl SerializeRow for &T { } } +#[allow(deprecated)] impl SerializeRow for LegacySerializedValues { fallback_impl_contents!(); } +#[allow(deprecated)] impl SerializeRow for Cow<'_, LegacySerializedValues> { fallback_impl_contents!(); } @@ -409,6 +411,10 @@ impl_tuples!( /// } /// impl_serialize_row_via_value_list!(WithGenerics); /// ``` +#[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" +)] #[macro_export] macro_rules! impl_serialize_row_via_value_list { ($t:ident$(<$($targ:tt $(: $tbound:tt)?),*>)?) => { @@ -440,8 +446,13 @@ macro_rules! impl_serialize_row_via_value_list { /// /// See the [`impl_serialize_row_via_value_list`] macro on information about /// the properties of the [`SerializeRow`] implementation. +#[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" +)] pub struct ValueListAdapter(pub T); +#[allow(deprecated)] impl SerializeRow for ValueListAdapter where T: ValueList, @@ -482,6 +493,11 @@ where /// /// See [`impl_serialize_row_via_value_list`] which generates a boilerplate /// [`SerializeRow`] implementation that uses this function. +#[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" +)] +#[allow(deprecated)] pub fn serialize_legacy_row( r: &T, ctx: &RowSerializationContext<'_>, @@ -686,6 +702,11 @@ impl Display for BuiltinSerializationErrorKind { /// Describes a failure to translate the output of the [`ValueList`] legacy trait /// into an output of the [`SerializeRow`] trait. #[derive(Error, Debug)] +#[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" +)] +#[allow(deprecated)] pub enum ValueListToSerializeRowAdapterError { /// The values generated by the [`ValueList`] trait were provided in /// name-value pairs, and there is a column in the statement for which @@ -921,7 +942,9 @@ pub(crate) mod tests { use crate::frame::response::result::{ColumnSpec, ColumnType, TableSpec}; use crate::frame::types::RawValue; + #[allow(deprecated)] use crate::frame::value::{LegacySerializedValues, MaybeUnset, SerializedResult, ValueList}; + #[allow(deprecated)] use crate::types::serialize::row::ValueListAdapter; use crate::types::serialize::{RowWriter, SerializationError}; @@ -938,6 +961,7 @@ pub(crate) mod tests { ColumnSpec::borrowed(name, typ, TableSpec::borrowed("ks", "tbl")) } + #[allow(deprecated)] #[test] fn test_legacy_fallback() { let row = ( @@ -967,6 +991,7 @@ pub(crate) mod tests { assert_eq!(&legacy_data[2..], new_data); } + #[allow(deprecated)] #[test] fn test_legacy_fallback_with_names() { let sorted_row = ( @@ -1056,6 +1081,7 @@ pub(crate) mod tests { ColumnSpec::borrowed(name, typ, TableSpec::borrowed("ks", "tbl")) } + #[allow(deprecated)] #[test] fn test_legacy_wrapper() { struct Foo; diff --git a/scylla-cql/src/types/serialize/value.rs b/scylla-cql/src/types/serialize/value.rs index 78e169aa4..ce6cc19a0 100644 --- a/scylla-cql/src/types/serialize/value.rs +++ b/scylla-cql/src/types/serialize/value.rs @@ -15,6 +15,7 @@ use uuid::Uuid; use crate::frame::response::result::{ColumnType, CqlValue}; use crate::frame::types::vint_encode; +#[allow(deprecated)] use crate::frame::value::{ Counter, CqlDate, CqlDecimal, CqlDuration, CqlTime, CqlTimestamp, CqlTimeuuid, CqlVarint, MaybeUnset, Unset, Value, @@ -926,6 +927,10 @@ fn serialize_mapping<'t, 'b, K: SerializeValue + 't, V: SerializeValue + 't>( /// } /// impl_serialize_value_via_value!(WithGenerics); /// ``` +#[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" +)] #[macro_export] macro_rules! impl_serialize_value_via_value { ($t:ident$(<$($targ:tt $(: $tbound:tt)?),*>)?) => { @@ -952,8 +957,13 @@ macro_rules! impl_serialize_value_via_value { /// /// See the [`impl_serialize_value_via_value`] macro on information about /// the properties of the [`SerializeValue`] implementation. +#[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" +)] pub struct ValueAdapter(pub T); +#[allow(deprecated)] impl SerializeValue for ValueAdapter where T: Value, @@ -981,6 +991,11 @@ where /// /// See [`impl_serialize_value_via_value`] which generates a boilerplate /// [`SerializeValue`] implementation that uses this function. +#[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" +)] +#[allow(deprecated)] pub fn serialize_legacy_value<'b, T: Value>( v: &T, writer: CellWriter<'b>, @@ -1465,6 +1480,11 @@ impl Display for UdtSerializationErrorKind { /// Describes a failure to translate the output of the [`Value`] legacy trait /// into an output of the [`SerializeValue`] trait. +#[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" +)] +#[allow(deprecated)] #[derive(Error, Debug)] pub enum ValueToSerializeValueAdapterError { /// The value is too bit to be serialized as it exceeds the maximum 2GB size limit. @@ -1598,7 +1618,9 @@ pub(crate) mod tests { use std::collections::BTreeMap; use crate::frame::response::result::{ColumnType, CqlValue}; + #[allow(deprecated)] use crate::frame::value::{Counter, MaybeUnset, Unset, Value, ValueTooBig}; + #[allow(deprecated)] use crate::types::serialize::value::{ BuiltinSerializationError, BuiltinSerializationErrorKind, BuiltinTypeCheckError, BuiltinTypeCheckErrorKind, MapSerializationErrorKind, MapTypeCheckErrorKind, @@ -1612,6 +1634,7 @@ pub(crate) mod tests { use super::{SerializeValue, UdtSerializationErrorKind, UdtTypeCheckErrorKind}; + #[allow(deprecated)] fn check_compat(v: V) { let mut legacy_data = Vec::new(); ::serialize(&v, &mut legacy_data).unwrap(); @@ -1662,6 +1685,7 @@ pub(crate) mod tests { do_serialize_result(t, typ).unwrap_err() } + #[allow(deprecated)] #[test] fn test_legacy_wrapper() { struct Foo; diff --git a/scylla/src/lib.rs b/scylla/src/lib.rs index 6724a65d9..8dc56420a 100644 --- a/scylla/src/lib.rs +++ b/scylla/src/lib.rs @@ -144,6 +144,7 @@ pub mod serialize { }; // Legacy migration types - to be removed when removing legacy framework + #[allow(deprecated)] pub use scylla_cql::types::serialize::batch::{ LegacyBatchValuesAdapter, LegacyBatchValuesIteratorAdapter, }; @@ -161,6 +162,7 @@ pub mod serialize { }; // Legacy migration types - to be removed when removing legacy framework + #[allow(deprecated)] pub use scylla_cql::types::serialize::row::{ // Legacy migration types - to be removed when removing legacy framework serialize_legacy_row, @@ -188,6 +190,7 @@ pub mod serialize { }; // Legacy migration types - to be removed when removing legacy framework + #[allow(deprecated)] pub use scylla_cql::types::serialize::value::{ serialize_legacy_value, ValueAdapter, ValueToSerializeValueAdapterError, }; diff --git a/scylla/src/macros.rs b/scylla/src/macros.rs index ce64153e8..3e75fa1ab 100644 --- a/scylla/src/macros.rs +++ b/scylla/src/macros.rs @@ -30,6 +30,11 @@ pub use scylla_cql::macros::FromUserType; /// /// --- /// +#[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" +)] +#[allow(deprecated)] pub use scylla_cql::macros::IntoUserType; /// Derive macro for the [`SerializeValue`](crate::serialize::value::SerializeValue) trait @@ -486,6 +491,10 @@ pub use scylla_macros::DeserializeRow; /// /// --- /// +#[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" +)] pub use scylla_cql::macros::ValueList; #[deprecated( @@ -495,7 +504,9 @@ pub use scylla_cql::macros::ValueList; #[allow(deprecated)] pub use scylla_cql::macros::impl_from_cql_value_from_method; +#[allow(deprecated)] pub use scylla_cql::macros::impl_serialize_row_via_value_list; +#[allow(deprecated)] pub use scylla_cql::macros::impl_serialize_value_via_value; // Reexports for derive(IntoUserType)