A URI parser in Rust that strictly adheres to IETF [RFC 3986].
EStr
(Percent-encoded string slices):
All components in a URI that may be percent-encoded are parsed as EStr
s, which allows easy splitting and fast decoding:
rust
let query = "name=%E5%BC%A0%E4%B8%89&speech=%C2%A1Ol%C3%A9%21";
let map: HashMap<_, _> = EStr::new(query)
.split('&')
.filter_map(|pair| pair.split_once('='))
.map(|(k, v)| (k.decode(), v.decode()))
.filter_map(|(k, v)| k.into_string().ok().zip(v.into_string().ok()))
.collect();
assert_eq!(map["name"], "张三");
assert_eq!(map["speech"], "¡Olé!");
Three variants of Uri
for different use cases:
Uri<&str>
: borrowed; immutable.Uri<&mut [u8]>
: borrowed; in-place mutable.Uri<String>
: owned; immutable.Decode and extract query parameters in-place from a URI reference:
```rust fn decodeandextractquery( bytes: &mut [u8], ) -> Result<(Uri<&mut [u8]>, HashMap<&str, &str>), ParseError> { let mut uri = Uri::parsemut(bytes)?; let map = if let Some(query) = uri.takequery() { query .splitview('&') .flatmap(|pair| pair.splitonceview('=')) .map(|(k, v)| (k.decodeinplace(), v.decodeinplace())) .flatmap(|(k, v)| k.intostr().ok().zip(v.intostr().ok())) .collect() } else { HashMap::new() }; Ok((uri, map)) }
let mut bytes = *b"?lang=Rust&mascot=Ferris%20the%20crab"; let (uri, query) = decodeandextract_query(&mut bytes)?;
asserteq!(query["lang"], "Rust"); asserteq!(query["mascot"], "Ferris the crab");
// The query is taken from the Uri
.
assert!(uri.query().isnone());
// In-place decoding is like this if you're interested:
asserteq!(&bytes, b"?lang=Rust&mascot=Ferris the crabcrab");
```