diff --git a/scylla-cql/src/frame/response/cql_to_rust.rs b/scylla-cql/src/frame/response/cql_to_rust.rs index ec66d1e98e..9a95ffc803 100644 --- a/scylla-cql/src/frame/response/cql_to_rust.rs +++ b/scylla-cql/src/frame/response/cql_to_rust.rs @@ -4,7 +4,7 @@ use bigdecimal::BigDecimal; use chrono::{DateTime, Duration, NaiveDate, TimeZone, Utc}; use num_bigint::BigInt; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; -use std::hash::Hash; +use std::hash::{BuildHasher, Hash}; use std::net::IpAddr; use thiserror::Error; use uuid::Uuid; @@ -200,12 +200,12 @@ impl> FromCqlVal for Vec { } } -impl + Eq + Hash, T2: FromCqlVal> FromCqlVal - for HashMap +impl + Eq + Hash, T2: FromCqlVal, T3: BuildHasher + Default> + FromCqlVal for HashMap { fn from_cql(cql_val: CqlValue) -> Result { let vec = cql_val.into_pair_vec().ok_or(FromCqlValError::BadCqlType)?; - let mut res = HashMap::with_capacity(vec.len()); + let mut res = HashMap::with_capacity_and_hasher(vec.len(), T3::default()); for (key, value) in vec { res.insert(T1::from_cql(key)?, T2::from_cql(value)?); } @@ -213,14 +213,16 @@ impl + Eq + Hash, T2: FromCqlVal> FromCqlVal< } } -impl + Eq + Hash> FromCqlVal for HashSet { +impl + Eq + Hash, S: BuildHasher + Default> FromCqlVal + for HashSet +{ fn from_cql(cql_val: CqlValue) -> Result { cql_val .into_vec() .ok_or(FromCqlValError::BadCqlType)? .into_iter() .map(T::from_cql) - .collect::, FromCqlValError>>() + .collect::, FromCqlValError>>() } } diff --git a/scylla-cql/src/frame/value.rs b/scylla-cql/src/frame/value.rs index 9e927be3a3..e62469f4ef 100644 --- a/scylla-cql/src/frame/value.rs +++ b/scylla-cql/src/frame/value.rs @@ -8,6 +8,7 @@ use num_bigint::BigInt; use std::borrow::Cow; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::convert::TryInto; +use std::hash::BuildHasher; use std::net::IpAddr; use thiserror::Error; use uuid::Uuid; @@ -662,13 +663,13 @@ fn serialize_list_or_set<'a, V: 'a + Value>( Ok(()) } -impl Value for HashSet { +impl Value for HashSet { fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { serialize_list_or_set(self.iter(), self.len(), buf) } } -impl Value for HashMap { +impl Value for HashMap { fn serialize(&self, buf: &mut Vec) -> Result<(), ValueTooBig> { serialize_map(self.iter(), self.len(), buf) } @@ -851,9 +852,9 @@ impl ValueList for Vec { } // Implement ValueList for maps, which serializes named values -macro_rules! impl_value_list_for_map { - ($map_type:ident, $key_type:ty) => { - impl ValueList for $map_type<$key_type, T> { +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 = SerializedValues::with_capacity(self.len()); for (key, val) in self { @@ -866,10 +867,26 @@ macro_rules! impl_value_list_for_map { }; } -impl_value_list_for_map!(HashMap, String); -impl_value_list_for_map!(HashMap, &str); -impl_value_list_for_map!(BTreeMap, String); -impl_value_list_for_map!(BTreeMap, &str); +// 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 = SerializedValues::with_capacity(self.len()); + for (key, val) in self { + result.add_named_value(key, val)?; + } + + 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); // Implement ValueList for tuples of Values of size up to 16