| Crates.io | rou3 |
| lib.rs | rou3 |
| version | 0.1.0 |
| created_at | 2025-06-02 15:19:14.135597+00 |
| updated_at | 2025-06-02 15:19:14.135597+00 |
| description | 🌳 Lightweight and fast rou(ter) for Rust |
| homepage | |
| repository | https://github.com/MuntasirSZN/rou3-rs |
| max_upload_size | |
| id | 1698066 |
| size | 210,553 |
A flexible and fast HTTP router for Rust, inspired by rou3-js.
rou3-rs provides a high-performance routing solution for Rust applications, drawing inspiration from the design principles of rou3-js. It uses a trie-based structure with efficient hash map lookups for dynamic path segments and an optimized map for purely static routes.
/home, /about/contact/users/:id, /posts/:category/:slug/files/* (captures one segment)/assets/**:filepath (must be at the end)/search/:query? (matches /search/ and /search/term)"") to match any HTTP method.AHashMap for fast dynamic dispatch.static_map for instant lookups of purely static paths.findAllRoutes: Retrieve all routes that match a given path, useful for middleware or complex dispatch logic.parking_lot::RwLock.RouterError enum for robust error management.Add rou3-rs to your Cargo.toml:
[dependencies]
rou3 = "1.0.0"
Here's a quick overview of how to use rou3-rs:
use rou3::{Router, add_route, find_route, findAllRoutes, MatchedRoute, RouterError};
use std::collections::HashMap; // For easily checking params
fn main() -> Result<(), RouterError> {
// Create a new router. Let's say it stores string slices as data.
let router: Router<&'static str> = Router::new();
// 1. Add a static route
add_route(&router, "GET", "/home", "Welcome Home!")?;
// 2. Add a parameterized route
add_route(&router, "GET", "/users/:userId", "User Profile")?;
add_route(&router, "POST", "/users/:userId/message", "Send Message to User")?;
// 3. Add a wildcard route
add_route(&router, "GET", "/files/*", "Single File Wildcard")?; // Matches /files/report.pdf
add_route(&router, "GET", "/assets/**:filepath", "Serve Asset")?; // Matches /assets/css/style.css
// 4. Add a route with an optional parameter
add_route(&router, "GET", "/search/:query?", "Search Page")?;
// 5. Add a route for ANY HTTP method
add_route(&router, "", "/any/path", "Matches any method")?;
// --- Finding routes ---
// Find the static route
let home_route = find_route(&router, "GET", "/home", false)?; // capture_params = false
assert_eq!(home_route.data, "Welcome Home!");
assert!(home_route.params.is_none());
// Find a parameterized route and capture parameters
let user_route = find_route(&router, "GET", "/users/123", true)?; // capture_params = true
assert_eq!(user_route.data, "User Profile");
let expected_params = HashMap::from([("userId".to_string(), "123".to_string())]);
assert_eq!(user_route.params.map(|p| p.into_iter().collect::<HashMap<_,_>>()), Some(expected_params));
// Find a route matching the optional parameter (with value)
let search_with_query = find_route(&router, "GET", "/search/rust-router", true)?;
assert_eq!(search_with_query.data, "Search Page");
assert_eq!(
search_with_query.params.unwrap().get("query"),
Some(&"rust-router".to_string())
);
// Find a route matching the optional parameter (without value)
let search_without_query = find_route(&router, "GET", "/search/", true)?; // or /search
assert_eq!(search_without_query.data, "Search Page");
assert!(search_without_query.params.as_ref().map_or(true, |p| p.get("query").is_none() && p.is_empty()));
// Find a route using the ANY method
let any_method_route_get = find_route(&router, "GET", "/any/path", false)?;
assert_eq!(any_method_route_get.data, "Matches any method");
let any_method_route_post = find_route(&router, "POST", "/any/path", false)?;
assert_eq!(any_method_route_post.data, "Matches any method");
// --- Finding all matching routes ---
add_route(&router, "GET", "/config", "Config Base")?;
add_route(&router, "GET", "/config/:key", "Config Key Specific")?;
add_route(&router, "GET", "/config/**:path", "Config Wildcard")?;
let all_matches = findAllRoutes(&router, "GET", "/config/timeout", true);
println!("Found {} matches for /config/timeout:", all_matches.len());
for m in all_matches {
println!(" - Data: {}, Params: {:?}", m.data, m.params);
}
// Expected output would show 3 matches: Config Key Specific, Config Wildcard, and potentially a root wildcard if one was added.
Ok(())
}
rou3-rs is designed with performance in mind. It includes benchmarks comparing it against other popular Rust routers. For detailed results, please see the benchmark files in the benches directory and run cargo bench.
Contributions are welcome! Please feel free to submit issues, fork the repository, and create pull requests.
Ways to contribute:
This project is licensed under the MIT License - see the LICENSE file for details.