light_pencil/
datastructures.rs

1use 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}