diff --git a/Cargo.lock.msrv b/Cargo.lock.msrv index 0c816faa2..668bdec3f 100644 --- a/Cargo.lock.msrv +++ b/Cargo.lock.msrv @@ -91,7 +91,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -397,7 +397,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -408,7 +408,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -627,7 +627,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -1097,7 +1097,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -1241,18 +1241,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1354,7 +1354,7 @@ checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", "redox_syscall 0.2.16", - "thiserror", + "thiserror 1.0.48", ] [[package]] @@ -1510,7 +1510,7 @@ dependencies = [ "smallvec", "snap", "socket2", - "thiserror", + "thiserror 2.0.6", "time", "tokio", "tokio-openssl", @@ -1540,7 +1540,7 @@ dependencies = [ "serde", "snap", "stable_deref_trait", - "thiserror", + "thiserror 2.0.6", "time", "tokio", "uuid", @@ -1554,7 +1554,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -1571,7 +1571,7 @@ dependencies = [ "num-bigint 0.3.3", "rand", "scylla-cql", - "thiserror", + "thiserror 2.0.6", "tokio", "tracing", "tracing-subscriber", @@ -1604,7 +1604,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -1729,9 +1729,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.32" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -1746,7 +1746,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -1770,7 +1770,16 @@ version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.48", +] + +[[package]] +name = "thiserror" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec2a1820ebd077e2b90c4df007bebf344cd394098a13c563957d0afc83ea47" +dependencies = [ + "thiserror-impl 2.0.6", ] [[package]] @@ -1781,7 +1790,18 @@ checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d65750cab40f4ff1929fb1ba509e9914eb756131cef4210da8d5d700d26f6312" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] @@ -1872,7 +1892,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -1948,7 +1968,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -2121,7 +2141,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", "wasm-bindgen-shared", ] @@ -2143,7 +2163,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2365,7 +2385,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", "synstructure", ] @@ -2386,7 +2406,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -2406,7 +2426,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", "synstructure", ] diff --git a/scylla-cql/Cargo.toml b/scylla-cql/Cargo.toml index e80fa716d..9d18dfbd1 100644 --- a/scylla-cql/Cargo.toml +++ b/scylla-cql/Cargo.toml @@ -18,7 +18,7 @@ tokio = { version = "1.34", features = ["io-util", "time"] } secrecy-08 = { package = "secrecy", version = "0.8", optional = true } snap = "1.0" uuid = "1.0" -thiserror = "1.0" +thiserror = "2.0.6" num-bigint-03 = { package = "num-bigint", version = "0.3", optional = true } num-bigint-04 = { package = "num-bigint", version = "0.4", optional = true } bigdecimal-04 = { package = "bigdecimal", version = "0.4", optional = true } diff --git a/scylla-cql/src/frame/response/cql_to_rust.rs b/scylla-cql/src/frame/response/cql_to_rust.rs index a2a450ea9..89330c6e4 100644 --- a/scylla-cql/src/frame/response/cql_to_rust.rs +++ b/scylla-cql/src/frame/response/cql_to_rust.rs @@ -10,6 +10,11 @@ use std::net::IpAddr; use thiserror::Error; use uuid::Uuid; +#[deprecated( + since = "0.15.1", + note = "Legacy deserialization API is inefficient and is going to be removed soon" +)] +#[allow(deprecated)] #[derive(Error, Debug, Clone, PartialEq, Eq)] pub enum FromRowError { #[error("{err} in the column with index {column}")] @@ -29,6 +34,10 @@ pub trait FromCqlVal: Sized { fn from_cql(cql_val: T) -> Result; } +#[deprecated( + since = "0.15.1", + note = "Legacy deserialization API is inefficient and is going to be removed soon" +)] #[derive(Error, Debug, Clone, PartialEq, Eq)] pub enum FromCqlValError { #[error("Bad CQL type")] @@ -99,6 +108,10 @@ impl> FromCqlVal> for Option { /// /// impl_from_cql_value_from_method!(MyBytes, into_my_bytes); /// ``` +#[deprecated( + since = "0.15.1", + note = "Legacy deserialization API is inefficient and is going to be removed soon" +)] #[macro_export] macro_rules! impl_from_cql_value_from_method { ($T:ty, $convert_func:ident) => { diff --git a/scylla-cql/src/frame/response/result.rs b/scylla-cql/src/frame/response/result.rs index 5c192b0cb..02620de53 100644 --- a/scylla-cql/src/frame/response/result.rs +++ b/scylla-cql/src/frame/response/result.rs @@ -2410,6 +2410,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..0db6f503a 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,768 @@ 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, -} +#[deprecated( + since = "0.15.1", + note = "Legacy serialization API is not type-safe and is going to be removed soon" +)] +mod legacy { + #![allow(deprecated)] -pub type SerializedResult<'a> = Result, SerializeValuesError>; + use super::*; -/// 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(()) + /// 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>; } -} -impl Default for LegacySerializedValues { - fn default() -> Self { - Self::new() + /// 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, } -} -impl LegacySerializedValues { - /// Creates empty value list - pub const fn new() -> Self { - LegacySerializedValues { - serialized_values: Vec::new(), - values_num: 0, - contains_names: false, - } - } + 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); - pub fn with_capacity(capacity: usize) -> Self { - LegacySerializedValues { - serialized_values: Vec::with_capacity(capacity), - values_num: 0, - contains_names: false, + Ok(()) } } - pub fn has_names(&self) -> bool { - self.contains_names + impl Default for LegacySerializedValues { + fn default() -> Self { + Self::new() + } } - /// A const empty instance, useful for taking references - pub const EMPTY: &'static LegacySerializedValues = &LegacySerializedValues::new(); + impl LegacySerializedValues { + /// Creates empty value list + pub const fn new() -> Self { + LegacySerializedValues { + serialized_values: Vec::new(), + values_num: 0, + contains_names: false, + } + } - /// 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); + pub fn with_capacity(capacity: usize) -> Self { + LegacySerializedValues { + serialized_values: Vec::with_capacity(capacity), + values_num: 0, + contains_names: false, + } } - if self.values_num == u16::MAX { - return Err(SerializeValuesError::TooManyValues); + + pub fn has_names(&self) -> bool { + self.contains_names } - let len_before_serialize: usize = self.serialized_values.len(); + /// A const empty instance, useful for taking references + pub const EMPTY: &'static LegacySerializedValues = &LegacySerializedValues::new(); - if let Err(e) = val.serialize(&mut self.serialized_values) { - self.serialized_values.resize(len_before_serialize, 0); - return Err(SerializeValuesError::from(e)); - } + /// 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); + } - self.values_num += 1; - Ok(()) - } + let len_before_serialize: usize = self.serialized_values.len(); - 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); + 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(()) } - let len_before_serialize: usize = self.serialized_values.len(); + 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(); + + 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(()) - } + 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, + 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[..]); - } + pub fn is_empty(&self) -> bool { + self.values_num == 0 + } - pub fn is_empty(&self) -> bool { - self.values_num == 0 - } + pub fn len(&self) -> u16 { + self.values_num + } - pub fn len(&self) -> u16 { - self.values_num - } + pub fn size(&self) -> usize { + self.serialized_values.len() + } - pub fn size(&self) -> usize { - self.serialized_values.len() + 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) - }) + #[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")) + /// 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) + 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; + } + 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 + 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 +1453,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 +1590,143 @@ 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 -// + // + // 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 ()>, -} + /// 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 ()>, + } -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> 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, -} + 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 +1779,113 @@ 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 + 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-proxy/Cargo.toml b/scylla-proxy/Cargo.toml index 4f4ee627f..c54172a6e 100644 --- a/scylla-proxy/Cargo.toml +++ b/scylla-proxy/Cargo.toml @@ -28,7 +28,7 @@ tokio = { version = "1.34", features = [ "rt-multi-thread", ] } uuid = "1.0" -thiserror = "1.0.32" +thiserror = "2.0.6" bigdecimal = "0.4" num-bigint = "0.3" tracing = "0.1.25" diff --git a/scylla/Cargo.toml b/scylla/Cargo.toml index 6726b76b5..86284a5fd 100644 --- a/scylla/Cargo.toml +++ b/scylla/Cargo.toml @@ -59,7 +59,7 @@ tokio = { version = "1.34", features = [ snap = "1.0" uuid = { version = "1.0", features = ["v4"] } rand = "0.8.3" -thiserror = "1.0" +thiserror = "2.0.6" itertools = "0.13.0" tracing = "0.1.36" chrono = { version = "0.4.32", default-features = false, features = ["clock"] } 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) diff --git a/scylla/src/transport/errors.rs b/scylla/src/transport/errors.rs index 634e2a91b..7d835f269 100644 --- a/scylla/src/transport/errors.rs +++ b/scylla/src/transport/errors.rs @@ -34,15 +34,15 @@ use thiserror::Error; use crate::{authentication::AuthError, frame::response}; -use super::{ - iterator::NextRowError, - legacy_query_result::IntoLegacyQueryResultError, - query_result::{IntoRowsResultError, SingleRowError}, -}; +use super::iterator::NextRowError; +#[allow(deprecated)] +use super::legacy_query_result::IntoLegacyQueryResultError; +use super::query_result::{IntoRowsResultError, SingleRowError}; /// Error that occurred during query execution #[derive(Error, Debug, Clone)] #[non_exhaustive] +#[allow(deprecated)] pub enum QueryError { /// Database sent a response containing some error with a message #[error("Database returned an error: {0}, Error message: {1}")] @@ -115,6 +115,11 @@ pub enum QueryError { /// Failed to convert [`QueryResult`][crate::transport::query_result::QueryResult] /// into [`LegacyQueryResult`][crate::transport::legacy_query_result::LegacyQueryResult]. + #[deprecated( + since = "0.15.1", + note = "Legacy deserialization API is inefficient and is going to be removed soon" + )] + #[allow(deprecated)] #[error("Failed to convert `QueryResult` into `LegacyQueryResult`: {0}")] IntoLegacyQueryResultError(#[from] IntoLegacyQueryResultError), } @@ -181,6 +186,7 @@ impl From for NewSessionError { QueryError::BrokenConnection(e) => NewSessionError::BrokenConnection(e), QueryError::UnableToAllocStreamId => NewSessionError::UnableToAllocStreamId, QueryError::RequestTimeout(msg) => NewSessionError::RequestTimeout(msg), + #[allow(deprecated)] QueryError::IntoLegacyQueryResultError(e) => { NewSessionError::IntoLegacyQueryResultError(e) } @@ -204,6 +210,7 @@ impl From for QueryError { /// Error that occurred during session creation #[derive(Error, Debug, Clone)] #[non_exhaustive] +#[allow(deprecated)] pub enum NewSessionError { /// Failed to resolve hostname passed in Session creation #[error("Couldn't resolve any hostname: {0:?}")] @@ -286,6 +293,11 @@ pub enum NewSessionError { /// Failed to convert [`QueryResult`][crate::transport::query_result::QueryResult] /// into [`LegacyQueryResult`][crate::transport::legacy_query_result::LegacyQueryResult]. + #[deprecated( + since = "0.15.1", + note = "Legacy deserialization API is inefficient and is going to be removed soon" + )] + #[allow(deprecated)] #[error("Failed to convert `QueryResult` into `LegacyQueryResult`: {0}")] IntoLegacyQueryResultError(#[from] IntoLegacyQueryResultError), } diff --git a/scylla/src/transport/iterator.rs b/scylla/src/transport/iterator.rs index 8d7c07be3..f11d9dd73 100644 --- a/scylla/src/transport/iterator.rs +++ b/scylla/src/transport/iterator.rs @@ -1154,6 +1154,10 @@ mod legacy { } /// Couldn't get next typed row from the iterator + #[deprecated( + since = "0.15.1", + note = "Legacy deserialization API is inefficient and is going to be removed soon" + )] #[derive(Error, Debug, Clone)] pub enum LegacyNextRowError { /// Query to fetch next page has failed diff --git a/scylla/src/transport/legacy_query_result.rs b/scylla/src/transport/legacy_query_result.rs index 599174320..91fe47a58 100644 --- a/scylla/src/transport/legacy_query_result.rs +++ b/scylla/src/transport/legacy_query_result.rs @@ -11,6 +11,11 @@ use uuid::Uuid; /// Trait used to implement `Vec::into_typed` // This is the only way to add custom method to Vec +#[deprecated( + since = "0.15.1", + note = "Legacy deserialization API is inefficient and is going to be removed soon" +)] +#[allow(deprecated)] pub trait IntoTypedRows { fn into_typed(self) -> TypedRowIter; } @@ -28,6 +33,10 @@ impl IntoTypedRows for Vec { /// Iterator over rows parsed as the given type\ /// Returned by `rows.into_typed::<(...)>()` +#[deprecated( + since = "0.15.1", + note = "Legacy deserialization API is inefficient and is going to be removed soon" +)] pub struct TypedRowIter { row_iter: std::vec::IntoIter, phantom_data: std::marker::PhantomData, @@ -185,6 +194,10 @@ impl LegacyQueryResult { /// An error that occurred during [`QueryResult`](crate::transport::query_result::QueryResult) /// to [`LegacyQueryResult`] conversion. +#[deprecated( + since = "0.15.1", + note = "Legacy deserialization API is inefficient and is going to be removed soon" +)] #[non_exhaustive] #[derive(Error, Clone, Debug)] pub enum IntoLegacyQueryResultError { @@ -205,6 +218,11 @@ pub enum IntoLegacyQueryResultError { /// Expected `LegacyQueryResult.rows` to be `Some`, but it was `None`.\ /// `LegacyQueryResult.rows` is `Some` for queries that can return rows (e.g `SELECT`).\ /// It is `None` for queries that can't return rows (e.g `INSERT`). +#[deprecated( + since = "0.15.1", + note = "Legacy deserialization API is inefficient and is going to be removed soon" +)] +#[allow(deprecated)] #[derive(Debug, Clone, Error, PartialEq, Eq)] #[error( "LegacyQueryResult::rows() or similar function called on a bad LegacyQueryResult. @@ -259,6 +277,11 @@ pub enum FirstRowTypedError { FromRowError(#[from] FromRowError), } +#[deprecated( + since = "0.15.1", + note = "Legacy deserialization API is inefficient and is going to be removed soon" +)] +#[allow(deprecated)] #[derive(Debug, Clone, Error, PartialEq, Eq)] pub enum MaybeFirstRowTypedError { /// [`LegacyQueryResult::maybe_first_row_typed()`](LegacyQueryResult::maybe_first_row_typed) called on a bad LegacyQueryResult.\ @@ -273,6 +296,11 @@ pub enum MaybeFirstRowTypedError { FromRowError(#[from] FromRowError), } +#[deprecated( + since = "0.15.1", + note = "Legacy deserialization API is inefficient and is going to be removed soon" +)] +#[allow(deprecated)] #[derive(Debug, Clone, Error, PartialEq, Eq)] pub enum SingleRowError { /// [`LegacyQueryResult::single_row()`](LegacyQueryResult::single_row) called on a bad LegacyQueryResult.\ @@ -287,6 +315,11 @@ pub enum SingleRowError { BadNumberOfRows(usize), } +#[deprecated( + since = "0.15.1", + note = "Legacy deserialization API is inefficient and is going to be removed soon" +)] +#[allow(deprecated)] #[derive(Debug, Clone, Error, PartialEq, Eq)] pub enum SingleRowTypedError { /// [`LegacyQueryResult::single_row_typed()`](LegacyQueryResult::single_row_typed) called on a bad LegacyQueryResult.\ diff --git a/scylla/src/transport/load_balancing/default.rs b/scylla/src/transport/load_balancing/default.rs index 89220fbf2..16fd6ac9a 100644 --- a/scylla/src/transport/load_balancing/default.rs +++ b/scylla/src/transport/load_balancing/default.rs @@ -2853,6 +2853,7 @@ mod latency_awareness { | QueryError::DbError(DbError::RateLimitReached { .. }, _) => false, // "slow" errors, i.e. ones that are returned after considerable time of query being run + #[allow(deprecated)] QueryError::DbError(_, _) | QueryError::CqlResultParseError(_) | QueryError::CqlErrorParseError(_) diff --git a/scylla/src/transport/session.rs b/scylla/src/transport/session.rs index 11b413dad..90bdfead4 100644 --- a/scylla/src/transport/session.rs +++ b/scylla/src/transport/session.rs @@ -83,6 +83,7 @@ pub use crate::transport::connection_pool::PoolSize; // This re-export is to preserve backward compatibility. // Those items are no longer here not to clutter session.rs with legacy things. +#[allow(deprecated)] pub use crate::transport::legacy_query_result::{IntoTypedRows, TypedRowIter}; use crate::authentication::AuthenticatorProvider; diff --git a/scylla/src/transport/speculative_execution.rs b/scylla/src/transport/speculative_execution.rs index 60344d0a0..756ed3d89 100644 --- a/scylla/src/transport/speculative_execution.rs +++ b/scylla/src/transport/speculative_execution.rs @@ -110,6 +110,7 @@ fn can_be_ignored(result: &Result) -> bool { QueryError::EmptyPlan => false, // Errors that should not appear here, thus should not be ignored + #[allow(deprecated)] QueryError::NextRowError(_) | QueryError::IntoLegacyQueryResultError(_) | QueryError::TimeoutError