extern crate indexmap; extern crate take_some; use indexmap::IndexMap; use std::fmt; use std::hash::{BuildHasher, Hash}; use std::ops::{Deref, DerefMut}; use take_some::TakeSome; // Creating our own wrapper on top of the foreign type `IndexMap`. struct IndexMapWrapper(IndexMap); // Let's implement `Debug` so we can print out the map. impl fmt::Debug for IndexMapWrapper where K: fmt::Debug + Hash + Eq, V: fmt::Debug, S: BuildHasher, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self.0) } } // That's a very important trait that we definitely want to implement. // For more details see https://doc.rust-lang.org/std/ops/trait.Deref.html impl Deref for IndexMapWrapper { type Target = IndexMap; fn deref(&self) -> &Self::Target { &self.0 } } // Same story as with `Deref`: https://doc.rust-lang.org/std/ops/trait.DerefMut.html impl DerefMut for IndexMapWrapper { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } // An easy converter from an `IndexMap` to our own map. impl From> for IndexMapWrapper { fn from(origin: IndexMap) -> Self { IndexMapWrapper(origin) } } // And finally, a guest of honour... impl TakeSome for IndexMapWrapper where K: Eq + Hash, S: BuildHasher, { type Item = (K, V); fn take_some(&mut self) -> Option { // Thank Providence the `IndexMap` provides such a convenient way to pop out an element // out of it :) self.0.pop() } } fn main() { let mut map: IndexMapWrapper<_, _, _> = IndexMap::new().into(); // We can call method of `IndexMap` on `IndexMapWrapper` directly thanks to the `DerefMut` // trait. map.insert("Lol".to_string(), "wut".to_string()); map.insert("Ahaha".into(), "....".into()); println!("Originally we had: {:?}", map); // Okay, here comes the first test! let some_item = map.take_some(); assert!(some_item.is_some()); println!("Here's the `some` item: {:?}", some_item.unwrap()); // And here works the `Deref` trait. assert_eq!(1, map.len()); println!("The remainder: {:?}", map); // To see the output run `cargo run --example indexmap`. }