[][src]Macro nickel::middleware

macro_rules! middleware {
    (|$req:tt, mut $res:ident| <$data:path> $($b:tt)+) => { ... };
    (|$req:tt, $res:ident| <$data:path> $($b:tt)+) => { ... };
    (|$req:tt| <$data:path> $($b:tt)+) => { ... };
    (|$req:tt, mut $res:ident| $($b:tt)+) => { ... };
    (|$req:tt, $res:ident| $($b:tt)+) => { ... };
    (|$req:tt| $($b:tt)+) => { ... };
    ($($b:tt)+) => { ... };

Macro to reduce the boilerplate required for using unboxed closures as Middleware due to current type inference behaviour.

In future, the macro should hopefully be able to be removed while having minimal changes to the closure's code.


The body of the middleware! macro needs to return something implementing Responder. Some older examples had bodies that would return a MiddlewareResult, but this was exploiting an unsoundness in the Rust compiler that has since been tightened. See discussion at https://github.com/nickel-org/nickel.rs/issues/399.

Due to the way the macro is expanded, exiting the body early with a return statement will most likely fail with a cryptic error message. See https://github.com/nickel-org/nickel.rs/issues/389.


use nickel::{Nickel, HttpRouter};
use std::sync::atomic::{AtomicUsize, Ordering};

let mut server = Nickel::new();

// Some shared resource between requests, must be `Sync + Send`
let visits = AtomicUsize::new(0);

server.get("/", middleware! {
    format!("{}", visits.fetch_add(1, Ordering::Relaxed))


Type hinting

Sometimes type inference is unable to determine the datatype for the server, which can lead to a lot of extra type annotations. The middleware! macro supports annotating the macro so as to drive the inference allowing the handler code to remain with minimal annotations.

middleware! { |_request, _response| <MyServerData>
    // _response is of type Response<MyServerData>
    "Hello World"