diff --git a/scylla-cql/src/frame/response/cql_to_rust.rs b/scylla-cql/src/frame/response/cql_to_rust.rs index ec66d1e98e..f5facfef13 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; @@ -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..4e00a6d56e 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,7 +852,7 @@ impl ValueList for Vec { } // Implement ValueList for maps, which serializes named values -macro_rules! impl_value_list_for_map { +macro_rules! impl_value_list_for_btree_map { ($map_type:ident, $key_type:ty) => { impl ValueList for $map_type<$key_type, T> { fn serialized(&self) -> SerializedResult<'_> { @@ -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 { + ($map_type:ident, $key_type:ty) => { + impl ValueList for $map_type<$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!(HashMap, String); +impl_value_list_for_hash_map!(HashMap, &str); +impl_value_list_for_btree_map!(BTreeMap, String); +impl_value_list_for_btree_map!(BTreeMap, &str); // Implement ValueList for tuples of Values of size up to 16