light_pencil/
datastructures.rs1use std::iter;
2use std::borrow::Borrow;
3use std::collections::HashMap;
4use std::collections::hash_map;
5
6type MultiDictListIter<'a, T> = hash_map::Iter<'a, String, Vec<T>>;
7type MultiDictListValues<'a, T> = hash_map::Values<'a, String, Vec<T>>;
8
9pub struct MultiDictValues<'a, T: 'a> {
10 inner: iter::Map<MultiDictListValues<'a, T>, fn(&'a Vec<T>) -> &'a T>
11}
12
13impl<'a, T: 'a> iter::Iterator for MultiDictValues<'a, T> {
14 type Item = &'a T;
15 #[inline] fn next(&mut self) -> Option<&'a T> { self.inner.next() }
16 #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
17}
18
19pub struct MultiDictIter<'a, T: 'a> {
20 inner: iter::Map<MultiDictListIter<'a, T>, for<'b, 'c> fn((&'b String, &'c Vec<T>)) -> (&'b String, &'c T)>
21}
22
23impl<'a, T: 'a> iter::Iterator for MultiDictIter<'a, T> {
24 type Item = (&'a String, &'a T);
25 #[inline] fn next(&mut self) -> Option<(&'a String, &'a T)> { self.inner.next() }
26 #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
27}
28
29#[derive(Clone, Debug)]
30pub struct MultiDict<T> {
31 map: HashMap<String, Vec<T>>,
32}
33
34impl<T> MultiDict<T> {
35 pub fn new() -> MultiDict<T> {
36 MultiDict {
37 map: HashMap::new(),
38 }
39 }
40
41 pub fn get<B>(&self, key: &str) -> Option<&B>
42 where T: Borrow<B>,
43 B: ?Sized
44 {
45 match self.map.get(key) {
46 Some(value) => Some(value[0].borrow()),
47 None => None
48 }
49 }
50
51 pub fn set(&mut self, key: &str, value: T) {
52 self.map.insert(key.to_owned(), vec![value]);
53 }
54
55 pub fn add(&mut self, key: String, value: T) {
56 match self.map.remove(&key) {
57 Some(mut v) => {
58 v.push(value);
59 self.map.insert(key, v)
60 },
61 None => self.map.insert(key, vec![value]),
62 };
63 }
64
65 pub fn getlist(&self, key: &str) -> Option<&Vec<T>> {
66 self.map.get(key)
67 }
68
69 pub fn iter(&self) -> MultiDictIter<T> {
70 fn first<'a, 'b, A, B>(kvpair: (&'a A, &'b Vec<B>)) -> (&'a A, &'b B) { (kvpair.0, &kvpair.1[0]) }
71 MultiDictIter { inner: self.listiter().map(first) }
72 }
73
74 pub fn listiter(&self) -> hash_map::Iter<String, Vec<T>> {
75 self.map.iter()
76 }
77
78 pub fn keys(&self) -> hash_map::Keys<String, Vec<T>> {
79 self.map.keys()
80 }
81
82 pub fn values(&self) -> MultiDictValues<T> {
83 #[allow(ptr_arg)]
84 fn first<A>(list: &Vec<A>) -> &A { &list[0] }
85 MultiDictValues { inner: self.listvalues().map(first) }
86 }
87
88 pub fn listvalues(&self) -> hash_map::Values<String, Vec<T>> {
89 self.map.values()
90 }
91}