Skip to content

Commit 5e578e7

Browse files
committed
Auto merge of #449 - tomcc-reactor:master, r=Amanieu
Allow serializing `HashMap`s that use a custom allocator Hi, I'm using `HashMap` with custom allocators (eg. not `Global`) in my project, and I got hit with a "`HashMap` doesn't implement trait `Serialize`" error. It looks like it has a very trivial fix, eg. exposing the `A` generic parameter on the impl so that it doesn't default to `Global`. I have a very limited understanding of HashBrown so let me know if this is a change that makes sense! - Is `crate::raw::Allocator` the right way to import the `Allocator` trait? - Do you need `Deserialize` to be fixed as well? - What about `HashSet`? Anyway, if the change makes sense I can try to clean it up a bit more :)
2 parents b2190e2 + 065b6ee commit 5e578e7

File tree

1 file changed

+41
-22
lines changed

1 file changed

+41
-22
lines changed

src/external_trait_impls/serde.rs

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ mod size_hint {
1111
}
1212

1313
mod map {
14+
use crate::raw::Allocator;
1415
use core::fmt;
1516
use core::hash::{BuildHasher, Hash};
1617
use core::marker::PhantomData;
@@ -21,11 +22,12 @@ mod map {
2122

2223
use super::size_hint;
2324

24-
impl<K, V, H> Serialize for HashMap<K, V, H>
25+
impl<K, V, H, A> Serialize for HashMap<K, V, H, A>
2526
where
2627
K: Serialize + Eq + Hash,
2728
V: Serialize,
2829
H: BuildHasher,
30+
A: Allocator + Clone,
2931
{
3032
#[cfg_attr(feature = "inline-more", inline)]
3133
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -36,40 +38,46 @@ mod map {
3638
}
3739
}
3840

39-
impl<'de, K, V, S> Deserialize<'de> for HashMap<K, V, S>
41+
impl<'de, K, V, S, A> Deserialize<'de> for HashMap<K, V, S, A>
4042
where
4143
K: Deserialize<'de> + Eq + Hash,
4244
V: Deserialize<'de>,
4345
S: BuildHasher + Default,
46+
A: Allocator + Clone + Default,
4447
{
4548
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
4649
where
4750
D: Deserializer<'de>,
4851
{
49-
struct MapVisitor<K, V, S> {
50-
marker: PhantomData<HashMap<K, V, S>>,
52+
struct MapVisitor<K, V, S, A>
53+
where
54+
A: Allocator + Clone,
55+
{
56+
marker: PhantomData<HashMap<K, V, S, A>>,
5157
}
5258

53-
impl<'de, K, V, S> Visitor<'de> for MapVisitor<K, V, S>
59+
impl<'de, K, V, S, A> Visitor<'de> for MapVisitor<K, V, S, A>
5460
where
5561
K: Deserialize<'de> + Eq + Hash,
5662
V: Deserialize<'de>,
5763
S: BuildHasher + Default,
64+
A: Allocator + Clone + Default,
5865
{
59-
type Value = HashMap<K, V, S>;
66+
type Value = HashMap<K, V, S, A>;
6067

6168
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
6269
formatter.write_str("a map")
6370
}
6471

6572
#[cfg_attr(feature = "inline-more", inline)]
66-
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
73+
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
6774
where
68-
A: MapAccess<'de>,
75+
M: MapAccess<'de>,
6976
{
70-
let mut values = HashMap::with_capacity_and_hasher(
77+
let mut values = HashMap::with_capacity_and_hasher_in(
7178
size_hint::cautious(map.size_hint()),
7279
S::default(),
80+
A::default(),
7381
);
7482

7583
while let Some((key, value)) = map.next_entry()? {
@@ -89,6 +97,7 @@ mod map {
8997
}
9098

9199
mod set {
100+
use crate::raw::Allocator;
92101
use core::fmt;
93102
use core::hash::{BuildHasher, Hash};
94103
use core::marker::PhantomData;
@@ -99,10 +108,11 @@ mod set {
99108

100109
use super::size_hint;
101110

102-
impl<T, H> Serialize for HashSet<T, H>
111+
impl<T, H, A> Serialize for HashSet<T, H, A>
103112
where
104113
T: Serialize + Eq + Hash,
105114
H: BuildHasher,
115+
A: Allocator + Clone,
106116
{
107117
#[cfg_attr(feature = "inline-more", inline)]
108118
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -113,38 +123,44 @@ mod set {
113123
}
114124
}
115125

116-
impl<'de, T, S> Deserialize<'de> for HashSet<T, S>
126+
impl<'de, T, S, A> Deserialize<'de> for HashSet<T, S, A>
117127
where
118128
T: Deserialize<'de> + Eq + Hash,
119129
S: BuildHasher + Default,
130+
A: Allocator + Clone + Default,
120131
{
121132
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
122133
where
123134
D: Deserializer<'de>,
124135
{
125-
struct SeqVisitor<T, S> {
126-
marker: PhantomData<HashSet<T, S>>,
136+
struct SeqVisitor<T, S, A>
137+
where
138+
A: Allocator + Clone,
139+
{
140+
marker: PhantomData<HashSet<T, S, A>>,
127141
}
128142

129-
impl<'de, T, S> Visitor<'de> for SeqVisitor<T, S>
143+
impl<'de, T, S, A> Visitor<'de> for SeqVisitor<T, S, A>
130144
where
131145
T: Deserialize<'de> + Eq + Hash,
132146
S: BuildHasher + Default,
147+
A: Allocator + Clone + Default,
133148
{
134-
type Value = HashSet<T, S>;
149+
type Value = HashSet<T, S, A>;
135150

136151
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
137152
formatter.write_str("a sequence")
138153
}
139154

140155
#[cfg_attr(feature = "inline-more", inline)]
141-
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
156+
fn visit_seq<M>(self, mut seq: M) -> Result<Self::Value, M::Error>
142157
where
143-
A: SeqAccess<'de>,
158+
M: SeqAccess<'de>,
144159
{
145-
let mut values = HashSet::with_capacity_and_hasher(
160+
let mut values = HashSet::with_capacity_and_hasher_in(
146161
size_hint::cautious(seq.size_hint()),
147162
S::default(),
163+
A::default(),
148164
);
149165

150166
while let Some(value) = seq.next_element()? {
@@ -166,12 +182,15 @@ mod set {
166182
where
167183
D: Deserializer<'de>,
168184
{
169-
struct SeqInPlaceVisitor<'a, T, S>(&'a mut HashSet<T, S>);
185+
struct SeqInPlaceVisitor<'a, T, S, A>(&'a mut HashSet<T, S, A>)
186+
where
187+
A: Allocator + Clone;
170188

171-
impl<'a, 'de, T, S> Visitor<'de> for SeqInPlaceVisitor<'a, T, S>
189+
impl<'a, 'de, T, S, A> Visitor<'de> for SeqInPlaceVisitor<'a, T, S, A>
172190
where
173191
T: Deserialize<'de> + Eq + Hash,
174192
S: BuildHasher + Default,
193+
A: Allocator + Clone,
175194
{
176195
type Value = ();
177196

@@ -180,9 +199,9 @@ mod set {
180199
}
181200

182201
#[cfg_attr(feature = "inline-more", inline)]
183-
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
202+
fn visit_seq<M>(self, mut seq: M) -> Result<Self::Value, M::Error>
184203
where
185-
A: SeqAccess<'de>,
204+
M: SeqAccess<'de>,
186205
{
187206
self.0.clear();
188207
self.0.reserve(size_hint::cautious(seq.size_hint()));

0 commit comments

Comments
 (0)