I have a URL like this:
http%3A%2F%2Fexample.com%3Fa%3D1%26b%3D2%26c%3D3
I parsed it with hyper::Url::parse
and fetch the query string:
let parsed_url = hyper::Url::parse(&u).unwrap();
let query_string = parsed_url.query();
But it gives me the query as a string. I want to get the query string as HashMap
. something like this:
// some code to convert query string to HashMap
hash_query.get(&"a"); // eq to 1
hash_query.get(&"b"); // eq to 2
There are a few steps involved:
The .query_pairs()
method will give you an iterator over pairs of Cow<str>
.
Calling .into_owned()
on that will give you an iterator over String
pairs instead.
This is an iterator of (String, String)
, which is exactly the right shape to .collect()
into a HashMap<String, String>
.
Putting it together:
use std::collections::HashMap;
let parsed_url = Url::parse("http://example.com/?a=1&b=2&c=3").unwrap();
let hash_query: HashMap<_, _> = parsed_url.query_pairs().into_owned().collect();
assert_eq!(hash_query.get("a"), "1");
Note that you need a type annotation on the hash_query
—since .collect()
is overloaded, you have to tell the compiler which collection type you want.
If you need to handle repeated or duplicate keys, try the multimap
crate:
use multimap::MultiMap;
let parsed_url = Url::parse("http://example.com/?a=1&a=2&a=3").unwrap();
let hash_query: MultiMap<_, _> = parsed_url.query_pairs().into_owned().collect();
assert_eq!(hash_query.get_vec("a"), Some(&vec!["1", "2", "3"]));