AzLearn

تمرين إعادة البناء

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 })
}
اكتب هنا