sapper_query/
lib.rs

1
2use std::collections::HashMap;
3use std::collections::hash_map::Entry::*;
4use url::form_urlencoded;
5
6use sapper::{Request, Result, Key};
7
8pub type QueryMap = HashMap<String, Vec<String>>;
9
10pub struct QueryParams;
11impl Key for QueryParams { type Value = QueryMap; }
12
13pub fn parse(req: &mut Request) -> Result<()> {
14    let (_, query) = req.uri();
15    
16    if query.is_none() {
17        req.ext_mut().insert::<QueryParams>(HashMap::new());
18        return Ok(());
19    }
20    
21    let query_string = query.unwrap();
22
23    let query_iter = form_urlencoded::parse(query_string.as_bytes());
24
25    let mut deduplicated: QueryMap = HashMap::new();
26    for (key, val) in query_iter {
27        match deduplicated.entry(key.into_owned()) {
28            // Already a Vec here, push onto it
29            Occupied(entry) => { entry.into_mut().push(val.into_owned()); },
30
31            // No value, create a one-element Vec.
32            Vacant(entry) => { entry.insert(vec![val.into_owned()]); },
33        };
34    }
35    
36    req.ext_mut().insert::<QueryParams>(deduplicated);
37    
38    Ok(())
39}
40
41
42
43#[cfg(test)]
44mod tests {
45    #[test]
46    fn it_works() {
47    }
48}
49