I don't know what the best approach is. There's even more alternatives (I'm not claiming that any of those are necessarily better, either); you could something like qcell::QCell to re-gain the ability to mutate entries for your Rc approach
(in this case, removing items could use swap_remove on the vec and would need to update the index entries in the hash maps for both the removed item (removing the entries) and the one swapped into its place (updating the entries), unless the removed item was the last item)
You could have two hashmaps that map key to an index, and a Vec that stores the items at the given index. It's simple if you're only appending, and requires a bit of extra bookkeeping if you support removal.
Rust's generics and borrow checking add a layer of complexity here, but apart from that the problem is fundamental: where the data is stored, which of the keys is the primary key if any (for locality of access), and how do you ensure consistency across two indexes of the data.