Ideally it would behave as such:
let mut set: HashSet<(usize, usize)> = todo!(); // I imagine `(usize, usize)` will instead be some struct
set.insert((1, 10))?; // Returning an error if insertion of an overlapping pair was attempted
set.insert((20, 2))?; // e.g. (1, 2) would return an error
let other = set.get(1); // other = Some(10), or other = Some((1, 10)), either works, the 2nd is just redundant
let other = set.get(2); // other = Some(20)
I think this sums up the question.
I have read through the related question How to implement HashMap with two keys? but this covers a different approach and while it gives some ideas, I do not know enough to make the leap from those ideas to this implementation.
An ideal implementation may look like:
fn insert_pair<T: Hash + Eq + Clone>(map: &mut HashMap<T, T>, pair: (T, T)) -> Result<(), ()> {
match (map.entry(pair.0.clone()), map.entry(pair.1.clone())) {
(Entry::Vacant(a), Entry::Vacant(b)) => {
a.insert(pair.0);
b.insert(pair.1);
return Ok(());
}
_ => return Err(()),
}
}