Strict versions of the macros
By "strict" I mean ones that panic on duplicate keys/items.
The rationale has to do mostly with hashmaps that serve as "registries" of some sort. In my project, for example, there is a hashmap! of supported remote services where each one should have a unique textual identifier. As their number grows, I've became somewhat concerned about accidental name clashes.
Something like hashmap_strict! would helpful in catching these kinds of problems. It doesn't have to be fancy at all; a simple hashmap.insert(k, v).and_then(|_| panic!("duplicate hashmap key: {:?}")); would be sufficient (and the Debug requirement for keys is in line with panicking functions in stdlib, e.g. expect).
That's interesting but I would prefer to do this in a way that didn't duplicate all the macros?
In my vec_map macro (for VecMap) that was modelled after the maplit macros, I got bitten by this. I ended up adding an assertion:
macro_rules! vec_map {
(@single $($x:tt)*) => (());
(@count $($rest:expr),*) => (<[()]>::len(&[$(vec_map!(@single $rest)),*]));
($($key:expr => $value:expr,)+) => { vec_map!($($key => $value),+) };
($($key:expr => $value:expr),*) => {
{
let _cap = vec_map!(@count $($key),*);
let mut _map = ::vec_map::VecMap::with_capacity(_cap);
$(
assert!(_map.insert($key, $value).is_none()); // panic if map literal contains duplicate keys
)*
_map
}
};
}
Then it looks like this:
assertion failed: _map.insert(key, value).is_none() With the line where the macro is called.
I think it'd make sense if the maplit macros also did this by default.
I just ran into this as well in a use case like this:
let entrysets = maplit::hashmap!{
"straightline" => maplit::hashmap!{
"A" => SynthEntry(1,1,1, (0, [(0,0),(0,0),(0,0)])),
"B" => SynthEntry(2,2,1, (1, [(1, 1),(0,0), (0,0)])),
"B" => SynthEntry(3,3,1, (2, [(1,1),(2,1), (0,0)])),
"B" => SynthEntry(4,4,1, (3, [(2,1),(3,1),(0,0)])),
}
};
(Context doesn't matter here). My expectation was that I'd get a compile-time error here because I used string literals as keys.