title: What's the idiomatic way to make a lookup table which uses field of the item as the key?
body: <p>I have a collection of <code>Foo</code>.</p>
  
  <pre><code>struct Foo {
      k: String,
      v: String,
  }
  </code></pre>
  
  <p>I want a <code>HashMap</code> which has the key <code>&amp;foo.k</code> and the value <code>foo</code>.</p>
  
  <p>Apparently, it is not possible without redesigning <code>Foo</code> by introducing <code>Rc</code> or clone/copy the <code>k</code>.</p>
  
  <pre><code>fn t1() {
      let foo = Foo { k: "k".to_string(), v: "v".to_string() };
      let mut a: HashMap&lt;&amp;str, Foo&gt; = HashMap::new();
      a.insert(&amp;foo.k, foo); // Error
  }
  </code></pre>
  
  <p>There seems to be a workaround by abusing <code>get()</code> from <code>HashSet</code> (<a href="https://play.rust-lang.org/?gist=c3a884d5761736dab76abd8af38ebe13&amp;version=stable&amp;backtrace=0" rel="nofollow noreferrer">Playground</a>):</p>
  
  <pre><code>use std::collections::{HashMap, HashSet};
  use std::hash::{Hash, Hasher, BuildHasher};
  use std::collections::hash_map::Entry::*;
  
  struct Foo {
      k: String,
      v: String,
  }
  
  impl PartialEq for Foo {
      fn eq(&amp;self, other: &amp;Self) -&gt; bool { self.k == other.k }
  }
  
  impl Eq for Foo {}
  
  impl Hash for Foo {
      fn hash&lt;H: Hasher&gt;(&amp;self, h: &amp;mut H) { self.k.hash(h); }
  }
  
  impl ::std::borrow::Borrow&lt;str&gt; for Foo {
      fn borrow(&amp;self) -&gt; &amp;str {
          self.k.as_str()
      }
  }
  
  fn t2() {
      let foo = Foo { k: "k".to_string(), v: "v".to_string() };
      let mut a: HashSet&lt;Foo&gt; = HashSet::new();
      a.insert(foo);
      let bar = Foo { k: "k".to_string(), v: "v".to_string() };
      let foo = a.get("k").unwrap();
      println!("{}", foo.v);
  }
  </code></pre>
  
  <p>This is pretty tedious. What if a <code>Foo</code> has multiple fields and different collections of <code>Foo</code> to key on different fields?</p>