Description
I have a usecase for IndexSet<T>
, where T
is a complex struct with a hash that is computed on a reduced subset of its fields. I would like to be able to provide just this reduced subset in order to construct a hash and retrieve the stored object, if available. hashbrown
already provides such an option via the RawEntry
API, https://docs.rs/hashbrown/0.9.1/hashbrown/hash_map/struct.HashMap.html#method.raw_entry. HashMap::raw_entry
returns a RawEntryBuilder
object, which in turn exposes RawEntryBuilder::from_hash
, https://docs.rs/hashbrown/0.9.1/hashbrown/hash_map/struct.RawEntryBuilder.html#method.from_hash. This method allows providing just a hash and not the entire object on which the hash is computed.
Consider the following example:
struct MyBigStruct {
name: String,
source: String,
contents: BigHeapAllocatedThing,
}
#[derive(Hash)]
struct HashEssence<'a> {
name: &'a str,
source: &'a str,
}
impl<'a> From<&'a MyBigStruct> for HashEssence<'a> {
fn from(big_struct: &'a MyBigStruct) -> Self {
HashEssence {
name: &big_struct.name,
source: &big_struct.source,
}
}
}
impl Hash for MyBigStruct {
fn hash<H: Hasher>(&self, hasher: &mut H) {
let essence: HashEssence<'_> = self.into();
essence.hash(hasher);
}
}
Here, the hashes calculated on HashEssence
and MyBigStruct
are the same. But since I cannot impl Borrow<HashEssence> for MyBigStruct
, I cannot use IndexSet::get
to pass in HashEssence
. If IndexSet
exposed a method akin to hashbrown's RawEntryBuilder
, I could construct a HashEssence
just from two &str
and calculate the hash that way.