2

I need a HashMap<K,V> where V is a trait (it will likely be Box or an Rc or something, that's not important), and I need to ensure that the map stores at most one of a given struct, and more importantly, that I can query the presence of (and retrieve/insert) items by their type. K can be anything that is unique to each type (a uint would be nice, but a String or even some large struct holding type information would be sufficient as long as it can be Eq and Hashable)

This is occurring in a library, so I cannot use an enum or such since new types can be added by external code.

I looked into std::any::TypeId but besides not working for non-'static types, it seems they aren't even unique (and allegedly collisions were achieved accidentally with a rather small number of types) so I'd prefer to avoid them if feasible since the number of types I'll have may be very large. (hence this is not a duplicate of this IMO)

I'd like something along the lines of a macro to ensure uniqueness but I can't figure out how to have some kind of global compile time counter. I could use a proper UUID, but it'd be nice to have guaranteed uniqueness since this is, in theory at least, statically determinable.

It is safe to assume that all relevant types are defined either in this lib or in a singular crate that directly depends on it, if that allows for a solution that might be otherwise impossible.

e.g. my thoughts are to generate ids for types in the lib, and also export a constant of the counter, which can be used by the consumer of the lib in the same macro (or a very similar one) but I don't see a way to have such a const value modified by const code in multiple places.

Is this possible or do I need some kind of build script that provides values before compile time?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Phi
  • 107
  • 6
  • >in theory at least, statically determinable. I think, it determinable only in one translation unit due to monomorphization :( – Angelicos Phosphoros Oct 04 '20 at 03:46
  • @AngelicosPhosphoros you may be right. This may only be doable in rust via std::any::TypeID... which has a soundness bug – Phi Oct 04 '20 at 15:32
  • I found that gotham.rs developers use TypeId: https://github.com/gotham-rs/gotham/blob/89c491fb4322bbc6fbcc8405c3a33e0634f7cbba/gotham/src/state/mod.rs#L48 – Angelicos Phosphoros Oct 05 '20 at 01:59
  • I caved and went with typeid, if I run into collisions I'll deal with it then. For anyone else looking into this, I believe a solution would be possible via e.g. the ctor crate (look into how serde typetag uses it perhaps) – Phi Oct 15 '20 at 04:23

0 Answers0