What is it?

Rouste is a generic and declarative URI based router written with insane Rust macros.

The basic idea is to generate a router in a convenient way with two macros:

  1. route!(pattern => handler): declare routes that associate a pattern to a handler
  2. route_with![routes]: generate the router from a list of routes. The router is a function from a URI (path and query string) to a "maybe something" type that will try to match the route corresponding to the given URI and execute the associated handler

Rouste is generic in the sense that routes can capture any value from the URI and they can return any value as long as every handler of the same router return the same type.

Getting started

Add rouste dependency in Cargo.toml:

rouste = "0.1.3"

Declaring a route

Declare a route with the route! macro. This macro has two parameters: a pattern and a handler. If the pattern matches the URI, the handler will be executed. The pattern can capture data from the URI for the handler. Data can be captured from URI segments and query parameters. Uncaptured data are represented by a Rust identifier in the pattern and captured data are represented by a token tree of the form (identifier: type) where type implements the FromStr trait.

The following route will try to match the root or an empty URI and call handler_default:

rust route!(/ => handle_default)

rust fn handle_default() {}

This route will match an URI of the form "/say/my/name" where name can be any string. The handler must have a only one parameter which is a String:

rust route!(/say/my/(name: String) => print_name)

rust fn print_name(name: String) { println!("{}, you're goddamn right", name); }

As query parameters are optional, they are captured and passed as Options. A query parameter can be in the form KEY or KEY=VALUE. A KEY only query parameter is denoted by a Rust identifier and when captured its value is unit ():

rust route!(/fibonacci/(n: usize)?(f0: u32)&(f1: u32)&log => fibonacci)

```rust fn fibonacci(n: usize, maybef0: Option, maybef1: Option, maybelog: Option<()>) -> u32 { let f0 = maybef0.unwrapor(0); let f1 = maybef1.unwrapor(1); let mut fibonumber: Vec = vec![f0, f1];

for i in 0 ..= n {
    if maybe_log.is_some() {
        println!("{}", fibo_number[i]);
    }
    let current = fibo_number[i];
    let next = fibo_number[i + 1];
    fibo_number.push(current + next);
}

fibo_number[n]

} ```

Declaring a router

A router is defined by a list of routes. Handlers must have the same return type:

```rust fn handle_default() -> u32 { fibonacci(0) }

fn fibonacci(n: u32) -> u32 { match n { 0 => 0, 1 => 1, n => fibonacci(n - 1) + fibonacci(n - 2) } }

fn main() { let fibonaccirouter = routewith![ route!(/ => handle_default) , route!(/(n: u32) => fibonacci) ];

assert_eq!(fibonacci_router("/"), Some(0));
assert_eq!(fibonacci_router("/invalid"), None);
assert_eq!(fibonacci_router("/0"), Some(0));
assert_eq!(fibonacci_router("/1"), Some(1));
assert_eq!(fibonacci_router("/10"), Some(55));

} ```