prefix_tree_map 0.2.1

A Rust implementation of generic prefix tree (trie) map with wildcard capture support
Documentation
use prefix_tree_map::{Captures, KeyPart, PrefixTreeMap, PrefixTreeMapBuilder};

struct Router {
    table: PrefixTreeMap<&'static str, Param, Handler>,
}

#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)]
enum Param {
    UserId,
    ProductId,
}

enum Handler {
    User,
    Product,
}

fn user_handler(id: &str) {
    println!("user: {}", id);
}

fn product_handler(id: &str) {
    println!("product: {}", id);
}

impl Router {
    fn new() -> Self {
        let mut builder = PrefixTreeMapBuilder::new();

        let user_url = "/user/:user_id/home";
        let product_url = "/product/:product_id/info";

        builder.insert(
            user_url.split('/').map(|part| {
                if part == ":user_id" {
                    KeyPart::Wildcard(Param::UserId)
                } else {
                    KeyPart::Exact(part)
                }
            }),
            Handler::User,
        );

        builder.insert(
            product_url.split('/').map(|part| {
                if part == ":product_id" {
                    KeyPart::Wildcard(Param::ProductId)
                } else {
                    KeyPart::Exact(part)
                }
            }),
            Handler::Product,
        );

        Self {
            table: builder.build(),
        }
    }

    fn route(&self, path: &str) {
        let key = path.split('/').collect::<Vec<_>>();

        let mut capture_map = Map::new();

        match self.table.find_and_capture(&key, &mut capture_map) {
            Some(Handler::User) => user_handler(capture_map.captures[0].as_ref().unwrap()),
            Some(Handler::Product) => product_handler(capture_map.captures[1].as_ref().unwrap()),
            None => println!("not found"),
        }
    }
}

struct Map {
    pub captures: [Option<String>; 2],
}

impl Map {
    fn new() -> Self {
        Self {
            captures: [None, None],
        }
    }
}

impl Captures<Param, &str> for Map {
    fn insert(&mut self, key: Param, value: &str) {
        match key {
            Param::UserId => self.captures[0] = Some(value.to_string()),
            Param::ProductId => self.captures[1] = Some(value.to_string()),
        }
    }
}

fn main() {
    let router = Router::new();

    router.route("/user/00000/home");
    router.route("/user/0123456/home");
    router.route("/product/1234/info");
}