handy provides handles and handle maps. A handle map is a fairly useful
data structure for rust code, since it can help you work around borrow
HandleMap are a more robust version of the
pattern where instead of storing a reference to a &T directly, you instead
usize which indicates where it is in some
Vec. I claim they're
more robust because:
They can detect if you try to use a handle in a map other than the one that provided it.
If you remove an item from the HandleMap, the handle map won't let you use the stale handle to get whatever value happens to be in that index at the time.
let mut m = HandleMap::new(); let h0 = m.insert(3u32); assert_eq!(m[h0], 3); m.remove(h0); assert_eq!(m.get(h0), None);
A whole bunch.
slotmap: Same idea as this, but it requires
T: Copy(there's a way around this but it's a pain IMO). Has a system for defining handles for use in specific maps, but can't detect if you use a key from one map in another, if the maps are the same type. It also has a bunch of other maps for different performance cases but honestly the limitation of
T: Copyhas prevented me from digging too deeply.
slab: Also the same idea but you might not realize it from the docs. It can't detect use with the wrong map or use after the item is removed and another occupies the same spot.
HandleMap: I wrote this one. It's very similar, but with some different tradeoffs, and essentially different code. Also, this library doesn't bring in as many heavyweight dependencies, has more features, and isn't focused on use inside the FFI.
Unlike any of them, we're usable in no_std situations (we do link with
extern crate alloc, of course).
This module provides [
An untyped reference to some value. Handles are just a fancy u64.
An allocator for handle values. This is useful if you need direct control over handle storage, for example if you want use this library just to provide abstract generational indices which can be used in multiple backing arrays.
An iterator that moves out of a HandleMap.