Skip to content

Commit 1262825

Browse files
committed
Making the deserialization for LinkedHashMap generic for build hasher type
1 parent c59f5c1 commit 1262825

File tree

3 files changed

+75
-39
lines changed

3 files changed

+75
-39
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ serde = { version = "1.0", optional = true }
2222

2323
[dev-dependencies]
2424
serde_test = "1.0"
25+
fxhash = "0.2.1"

src/serde.rs

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -31,54 +31,59 @@ where
3131
}
3232
}
3333

34-
#[derive(Debug)]
35-
pub struct LinkedHashMapVisitor<K, V> {
36-
marker: PhantomData<LinkedHashMap<K, V>>,
37-
}
38-
39-
impl<K, V> LinkedHashMapVisitor<K, V> {
40-
fn new() -> Self {
41-
LinkedHashMapVisitor {
42-
marker: PhantomData,
43-
}
44-
}
45-
}
46-
47-
impl<K, V> Default for LinkedHashMapVisitor<K, V> {
48-
fn default() -> Self {
49-
Self::new()
50-
}
51-
}
52-
53-
impl<'de, K, V> Visitor<'de> for LinkedHashMapVisitor<K, V>
34+
impl<'de, K, V, S> Deserialize<'de> for LinkedHashMap<K, V, S>
5435
where
5536
K: Deserialize<'de> + Eq + Hash,
5637
V: Deserialize<'de>,
38+
S: BuildHasher + Default,
5739
{
58-
type Value = LinkedHashMap<K, V>;
59-
60-
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
61-
write!(formatter, "a map")
62-
}
40+
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
41+
#[derive(Debug)]
42+
pub struct LinkedHashMapVisitor<K, V, S> {
43+
marker: PhantomData<LinkedHashMap<K, V, S>>,
44+
}
6345

64-
#[inline]
65-
fn visit_map<M: MapAccess<'de>>(self, mut map: M) -> Result<Self::Value, M::Error> {
66-
let mut values = LinkedHashMap::with_capacity(map.size_hint().unwrap_or(0));
46+
impl<K, V, S> LinkedHashMapVisitor<K, V, S> {
47+
fn new() -> Self {
48+
LinkedHashMapVisitor {
49+
marker: PhantomData,
50+
}
51+
}
52+
}
6753

68-
while let Some((k, v)) = map.next_entry()? {
69-
values.insert(k, v);
54+
impl<K, V, S> Default for LinkedHashMapVisitor<K, V, S> {
55+
fn default() -> Self {
56+
Self::new()
57+
}
7058
}
7159

72-
Ok(values)
73-
}
74-
}
60+
impl<'de, K, V, S> Visitor<'de> for LinkedHashMapVisitor<K, V, S>
61+
where
62+
K: Deserialize<'de> + Eq + Hash,
63+
V: Deserialize<'de>,
64+
S: BuildHasher + Default,
65+
{
66+
type Value = LinkedHashMap<K, V, S>;
67+
68+
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
69+
write!(formatter, "a map")
70+
}
71+
72+
#[inline]
73+
fn visit_map<M: MapAccess<'de>>(self, mut map: M) -> Result<Self::Value, M::Error> {
74+
let mut values = LinkedHashMap::with_capacity_and_hasher(
75+
map.size_hint().unwrap_or(0),
76+
S::default(),
77+
);
78+
79+
while let Some((k, v)) = map.next_entry()? {
80+
values.insert(k, v);
81+
}
82+
83+
Ok(values)
84+
}
85+
}
7586

76-
impl<'de, K, V> Deserialize<'de> for LinkedHashMap<K, V>
77-
where
78-
K: Deserialize<'de> + Eq + Hash,
79-
V: Deserialize<'de>,
80-
{
81-
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
8287
deserializer.deserialize_map(LinkedHashMapVisitor::default())
8388
}
8489
}

tests/serde.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![cfg(feature = "serde_impl")]
22

3+
use fxhash::FxBuildHasher;
34
use hashlink::{LinkedHashMap, LinkedHashSet};
45
use serde_test::{assert_tokens, Token};
56

@@ -32,6 +33,35 @@ fn map_serde_tokens() {
3233
);
3334
}
3435

36+
#[test]
37+
fn map_serde_tokens_empty_generic() {
38+
let map = LinkedHashMap::<char, u32>::new();
39+
40+
assert_tokens(&map, &[Token::Map { len: Some(0) }, Token::MapEnd]);
41+
}
42+
43+
#[test]
44+
fn map_serde_tokens_generic() {
45+
let mut map = LinkedHashMap::with_hasher(FxBuildHasher::default());
46+
map.insert('a', 10);
47+
map.insert('b', 20);
48+
map.insert('c', 30);
49+
50+
assert_tokens(
51+
&map,
52+
&[
53+
Token::Map { len: Some(3) },
54+
Token::Char('a'),
55+
Token::I32(10),
56+
Token::Char('b'),
57+
Token::I32(20),
58+
Token::Char('c'),
59+
Token::I32(30),
60+
Token::MapEnd,
61+
],
62+
);
63+
}
64+
3565
#[test]
3666
fn set_serde_tokens_empty() {
3767
let set = LinkedHashSet::<u32>::new();

0 commit comments

Comments
 (0)