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
Yes, that's what you should be doing. encodeURIComponent is the correct way to encode a text value for putting in part of a query string. but when it is decoded at the server, the parameters of url are interpreted as seperate parameters and not as part of the single url parameter.
The PHP Server object provides access to the query string for a page URL. Add the following code to retrieve it: $query_string = $_SERVER['QUERY_STRING']; This code stores the query string in a variable, having retrieved it from the Server object.
A query string is a part of a uniform resource locator (URL) that assigns values to specified parameters.
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"]));
The other answer is good, but I feel that this is something that should be more straightforward, so I wrapped it in a function:
use {
std::collections::HashMap,
url::Url
};
fn query(u: Url) -> HashMap<String, String> {
u.query_pairs().into_owned().collect()
}
fn main() -> Result<(), url::ParseError> {
let u = Url::parse("http://stackoverflow.com?month=May&day=Friday")?;
let q = query(u);
println!("{:?}", q);
Ok(())
}
Alternatively, I found another crate that does this for you:
use auris::URI;
fn main() -> Result<(), auris::ParseError> {
let s = "http://stackoverflow.com?month=May&day=Friday";
let u: URI<String> = s.parse()?;
println!("{:?}", u.qs); // Some({"month": "May", "day": "Friday"})
Ok(())
}
https://docs.rs/auris
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With