struct Id {
id: u32
}
impl Hash for Id {
fn hash<H>(&self, state: &mut H)
where
H: Hasher
{
self.id.hash(state);
}
}
impl PartialEq for Id {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
There's obviously more to it than that (in particular there's a Drop implementation for Id), but for the purposes of my question it's a proxy around a u32.
It's used like this:
let vconns: HashMap<Arc<Id>, Connection> = HashMap::new();
A situation has manifested itself where an application has access to a raw u32 (that is guaranteed to exist in the form of an Id in the HashMap). Assuming there's no way to create an Id from a u32, is there some way to:
Keep the HashMap's key an Arc<Id>
Allow a Connection to be looked up using an u32
Avoid introducing a second HashMap (to map u32's to Id's)
.. where the assumption is the hash of Arc<Id> will always be a proxy for an internal actual u32.
I'm using hashbrown's HashMap, and I had some vague memory of having used it to looked up items using manually calculated hash values, which would sort of fit here -- but I can't find how I could have done that, so I'm wondering if that was just a pizza dream.
Almost, but not quite. If your key type implements Borrow<U>, then HashMap will let you look things up using values of type &U. Unfortunately, Arc's Borrow implementation isn't transitive: As things stand right now, you can look only things up by &Arc<Id> or &Id. You also can't implement Borrow<u32> for Arc<Id> due to orphan rules.
You can, however, wrap Arc<Id> into a newtype and implement Borrow<u32> for that.
Alternatively, you can make a newtype for raw ids that doesn't have the drop machinery:
#[derive(Hash,Eq,PartialEq)]
struct RawId(u32);
#[derive(Hash,Eq,PartialEq)]
struct Id(RawId);
impl Borrow<RawId> for Id {
fn borrow(&self)->&RawId { &self.0 }
}
impl Borrow<RawId> for Arc<Id> {
fn borrow(&self)->&RawId { &self.0 }
}
// vconns.get(&RawId( external_id )) should work now
This is the first time that I ever heard these concepts applied to trait implementations. Any chance that you could post some literature to further dive / understand them?