تمرين إعادة البناء
Mini Router
أعد كتابة موجّه أوامر صغير يطابق المسارات والمعاملات من نص الطلب.
rust
~24 دقيقة
متوسط
أعد بناء الكود
Rebuild
هذا هو الكود. اكتبه بنفسك.
الكود المرجعي
use std::collections::HashMap;
use std::io::{self, Read};
#[derive(Debug)]
struct RouteMatch {
name: &'static str,
params: HashMap<String, String>,
}
fn main() -> io::Result<()> {
let mut input = String::new();
io::stdin().read_to_string(&mut input)?;
let path = input.trim();
let path = if path.is_empty() { "/orders/42" } else { path };
let routes = [
("home", "/"),
("product", "/products/:id"),
("order", "/orders/:id"),
("store_city", "/stores/:city/:slug"),
];
for (name, pattern) in routes {
if let Some(route_match) = match_route(name, pattern, path) {
println!("Matched: {}", route_match.name);
for (key, value) in route_match.params {
println!("{key}={value}");
}
return Ok(());
}
}
println!("No route matched");
Ok(())
}
fn match_route(name: &'static str, pattern: &str, path: &str) -> Option<RouteMatch> {
let pattern_parts: Vec<_> = pattern.trim_matches('/').split('/').collect();
let path_parts: Vec<_> = path.trim_matches('/').split('/').collect();
if pattern == "/" && path == "/" {
return Some(RouteMatch {
name,
params: HashMap::new(),
});
}
if pattern_parts.len() != path_parts.len() {
return None;
}
let mut params = HashMap::new();
for (pattern_part, path_part) in pattern_parts.iter().zip(path_parts.iter()) {
if let Some(key) = pattern_part.strip_prefix(':') {
params.insert(key.to_string(), (*path_part).to_string());
} else if pattern_part != path_part {
return None;
}
}
Some(RouteMatch { name, params })
}اكتب هنا