from_readme/
from_readme.rs

1extern crate total_order_multi_map as tomm;
2
3use std::fmt::{self, Display};
4use tomm::TotalOrderMultiMap;
5
6/// for now the key has to be copy
7type Key = &'static str;
8
9/// the map is made for thinks which dereference
10/// e.g. trait objects, through e.g. `String` or
11/// `Rc<Debug>` would be fine, too.
12type Value = Box<Display>;
13
14
15fn main() {
16    let mut map = TotalOrderMultiMap::<Key, Value>::new();
17
18    map.add("key1", mk_box_str("val1"));
19    map.add("key1", mk_my_thingy("val2"));
20    map.add("key2", mk_box_str("val3"));
21    map.add("key1", mk_my_thingy("val4"));
22    map.add("key0", mk_box_str("val5"));
23
24    let stringed = map
25        .iter()
26        // val is of type `&Display`
27        .map(|(key, val)| format!("{}:{}", key, val))
28        .collect::<Vec<_>>();
29
30    // as it can be seen the total insertion order was kept
31    assert_eq!(stringed, &[
32        "key1:val1".to_owned(),
33        "key1:val2".to_owned(),
34        "key2:val3".to_owned(),
35        "key1:val4".to_owned(),
36        "key0:val5".to_owned()
37    ]);
38
39    // It's also still a multi map.
40    // Note that the get operation has roughly the same
41    // performance as in a hash map (through you then
42    // iterate over the elements associated with the key
43    // roughly with the speed of iterating over an `Vec`).
44    {
45        let values = map.get("key1");
46        let stringed = values
47            .map(|val| format!("{}", val))
48            .collect::<Vec<_>>();
49
50        assert_eq!(stringed, &[ "val1", "val2", "val4" ]);
51    }
52
53    // but as we have an order we can remove
54    // "the last inserted" element
55    let (key, val) = map.pop().unwrap();
56    assert_eq!(format!("{}:{}", key, val), "key0:val5");
57
58    // or remove all for an specific key as it's
59    // an multi map
60    map.remove_all("key1");
61    assert_eq!(0, map.get("key1").len(), "expected no values for key1");
62
63    println!("DONE (I only contain asserts)")
64}
65
66//---- some function to create dummy values for the example ----
67
68fn mk_box_str(inp: &str) -> Box<Display> {
69    // sadly we can't cast Box<str> to Box<Display>
70    // (you would need non static vtables for this...)
71    Box::new(inp.to_owned())
72}
73
74#[derive(Debug)]
75struct MyThingy { val: String }
76
77impl Display for MyThingy {
78    fn fmt(&self, fter: &mut fmt::Formatter) -> fmt::Result {
79        write!(fter, "{}", self.val)
80    }
81}
82
83fn mk_my_thingy(inp: &str) -> Box<Display> {
84    Box::new(MyThingy { val: inp.to_owned() })
85}