Relax FormItems iterator slicing rules a little.

This commit is contained in:
CrLF0710 2017-04-02 01:13:38 +08:00
parent f5ec470a7d
commit 7830a09f1e
1 changed files with 41 additions and 17 deletions

View File

@ -212,23 +212,43 @@ impl<'f> Iterator for FormItems<'f> {
fn next(&mut self) -> Option<Self::Item> {
let s = &self.string[self.next_index..];
let (key, rest) = match memchr2(b'=', b'&', s.as_bytes()) {
Some(i) if s.as_bytes()[i] == b'=' => (&s[..i], &s[(i + 1)..]),
Some(_) => return None,
None => return None,
};
match memchr2(b'=', b'&', s.as_bytes()) {
Some(i) if s.as_bytes()[i] == b'=' => {
let (key, rest) = (&s[..i], &s[(i + 1)..]);
if key.is_empty() {
return None;
if key.is_empty() {
return None;
}
let (value, consumed) = match rest.find('&') {
Some(index) => (&rest[..index], index + 1),
None => (rest, rest.len()),
};
self.next_index += key.len() + 1 + consumed;
Some((key.into(), value.into()))
}
Some(i) => {
let (value, consumed) = (&s[..i], i + 1);
if value.is_empty() {
return None;
}
self.next_index += consumed;
Some(("".into(), value.into()))
}
None => {
let (value, consumed) = (&s[..], s.as_bytes().len());
if value.is_empty() {
return None;
}
self.next_index += consumed;
Some(("".into(), value.into()))
}
}
let (value, consumed) = match rest.find('&') {
Some(index) => (&rest[..index], index + 1),
None => (rest, rest.len()),
};
self.next_index += key.len() + 1 + consumed;
Some((key.into(), value.into()))
}
}
@ -282,9 +302,13 @@ mod test {
check_form!("user=&", &[("user", "")]);
check_form!("a=b&a=", &[("a", "b"), ("a", "")]);
check_form!(@bad "user=&password");
check_form!("user=&password", &[("user", ""), ("", "password")]);
check_form!("a=b&a", &[("a", "b"), ("", "a")]);
check_form!("a&b&c", &[("", "a"), ("", "b"), ("", "c")]);
check_form!("abc", &[("", "abc")]);
check_form!(@bad "user=x&&");
check_form!(@bad "a=b&a");
check_form!(@bad "=");
check_form!(@bad "&");
check_form!(@bad "=&");