FelixMoelder
FelixMoelder

Reputation: 31

Serializing rust HashMap with custom hash function

I'm trying to serialize a rust HashMap with a custom hash function applying bincode::serialize_into(writer, cache)?; where cache is a struct-object defined as following:

use std::hash::{BuildHasherDefault, Hasher};
use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize)]
pub(crate) struct Cache<S>
where
    S: Default + Hasher,
{
    records: HashMap<DNA, Mapping, BuildHasherDefault<S>>,
}

When compiling I receive an error the trait 'cli::_::_serde::Serialize' is not implemented for 'S' referring to the cache variable.

As described in this issue serialization for custom hash functions (in my case FnvHasher) should exist requiring only to implement the BuildHasher trait. That trait is already implemented by BuildHasherDefault which is used to create a BuildHasher instance.

Edit: To illustrate the issue I've create a playground example (as bincode is not available in playground I used serde_json instead). As the example shows it is possible to create and serialize a HashMap custom_hashmap with custom hash-function (in this case FnvHasher). But this does not work for a Cache-object cache wrapping a HashMap with a custom hash-function. In that case the compiler asks for adding the Serialize trait which does not exist for the FnvHasher

Upvotes: 3

Views: 1095

Answers (1)

Connor Clark
Connor Clark

Reputation: 55

Define custom bounds on the problematic field as documented here.

#[derive(Deserialize, Serialize)]
pub(crate) struct Cache<S>
where
    S: Default + Hasher,
{
    #[serde(bound(
        serialize = "HashMap<DNA, Mapping, BuildHasherDefault<S>>: Serialize",
        deserialize = "HashMap<DNA, Mapping, BuildHasherDefault<S>>: Deserialize<'de>"
    ))]
    records: HashMap<DNA, Mapping, BuildHasherDefault<S>>,
}

Full fixed playground link

Upvotes: 0

Related Questions