Skip to content

Commit f924161

Browse files
emilkhacknus
authored andcommitted
Location::query_map: support repeated key (emilk#4183)
This adds support for parsing e.g. `?foo=hello&foo=world`, returning both "hello" and "world" in `Location::query_map`
1 parent 2f87cdc commit f924161

File tree

2 files changed

+18
-15
lines changed

2 files changed

+18
-15
lines changed

crates/eframe/src/epi.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -758,8 +758,8 @@ pub struct Location {
758758

759759
/// The parsed "query" part of "www.example.com/index.html?query#fragment".
760760
///
761-
/// "foo=42&bar%20" is parsed as `{"foo": "42", "bar ": ""}`
762-
pub query_map: std::collections::BTreeMap<String, String>,
761+
/// "foo=hello&bar%20&foo=world" is parsed as `{"bar ": [""], "foo": ["hello", "world"]}`
762+
pub query_map: std::collections::BTreeMap<String, Vec<String>>,
763763

764764
/// `location.origin`
765765
///

crates/eframe/src/web/backend.rs

+16-13
Original file line numberDiff line numberDiff line change
@@ -117,21 +117,24 @@ pub fn web_location() -> epi::Location {
117117
}
118118

119119
/// query is percent-encoded
120-
fn parse_query_map(query: &str) -> BTreeMap<String, String> {
121-
query
122-
.split('&')
123-
.filter_map(|pair| {
124-
if pair.is_empty() {
125-
None
120+
fn parse_query_map(query: &str) -> BTreeMap<String, Vec<String>> {
121+
let mut map: BTreeMap<String, Vec<String>> = Default::default();
122+
123+
for pair in query.split('&') {
124+
if !pair.is_empty() {
125+
if let Some((key, value)) = pair.split_once('=') {
126+
map.entry(percent_decode(key))
127+
.or_default()
128+
.push(percent_decode(value));
126129
} else {
127-
Some(if let Some((key, value)) = pair.split_once('=') {
128-
(percent_decode(key), percent_decode(value))
129-
} else {
130-
(percent_decode(pair), String::new())
131-
})
130+
map.entry(percent_decode(pair))
131+
.or_default()
132+
.push(String::new());
132133
}
133-
})
134-
.collect()
134+
}
135+
}
136+
137+
map
135138
}
136139

137140
// TODO(emilk): this test is never acgtually run, because this whole module is wasm32 only 🤦‍♂️

0 commit comments

Comments
 (0)