Pybites Logo Rust Platform

URL Query Parameter Parser

Medium +3 pts

🎯 In Python, parsing structured strings into dicts is straightforward:

# colon-delimited key:value pairs
pairs = "name:Alice,age:30".split(",")
data = dict(p.split(":", 1) for p in pairs)

This exercise applies the same idea to URL query strings in Rust β€” a great chance to practice combining iterator methods into a real parsing pipeline.

String splitting

Rust's .split() works like Python's, returning an iterator over the pieces:

let parts: Vec<&str> = "a&b&c".split('&').collect();
// ["a", "b", "c"]

When you need to limit the number of splits, use .splitn(n, pattern) β€” like Python's str.split(':', 1):

let parts: Vec<&str> = "host:localhost:8080".splitn(2, ':').collect();
// ["host", "localhost:8080"]  β€” only splits on the first ':'

This matters when the value itself may contain the delimiter β€” you want to split into key and rest, not all pieces.

Multi-line closures

So far you've seen short closures like |x| x + 1. When you need multiple statements, use curly braces:

let results: Vec<i32> = items.iter().map(|item| {
    let doubled = item * 2;
    let adjusted = doubled + 1;
    adjusted
}).collect();

The last expression in the block is the closure's return value β€” same rule as functions.

Collecting tuples into a HashMap

You already know .collect() can build a Vec or String. It can also build a HashMap β€” if the iterator yields tuples of (key, value):

use std::collections::HashMap;

let pairs = vec![("name", "Alice"), ("age", "30")];
let map: HashMap<&str, &str> = pairs.into_iter().collect();

This is the Rust-idiomatic way to build a HashMap from parsed data β€” transform your input into an iterator of tuples, then .collect().

Handling missing values with .unwrap_or()

When pulling items from an iterator with .next(), the result is Option<T> β€” it might be None if the iterator is exhausted. .unwrap_or(default) provides a fallback:

let mut parts = "Alice:42".splitn(2, ':');
let name = parts.next().unwrap_or("unknown");  // "Alice"
let age = parts.next().unwrap_or("0");          // "42"

Your Task

Implement parse_query_params(query: &str) -> HashMap<String, String> that parses a URL query string like "name=John&age=30" into a HashMap of key-value pairs.

Handle edge cases: empty strings and parameters without values (e.g., "name=" β†’ ("name", "")).


Example

let params = parse_query_params("name=John&age=30");
assert_eq!(params.get("name"), Some(&"John".to_string()));
assert_eq!(params.get("age"), Some(&"30".to_string()));

Further Reading