Skip to main content

Handler

Trait Handler 

Source
pub trait Handler:
    Send
    + Sync
    + 'static {
    // Provided methods
    fn run(&self, conn: Conn) -> impl Future<Output = Conn> + Send { ... }
    fn init(&mut self, info: &mut Info) -> impl Future<Output = ()> + Send { ... }
    fn before_send(&self, conn: Conn) -> impl Future<Output = Conn> + Send { ... }
    fn has_upgrade(&self, upgrade: &Upgrade) -> bool { ... }
    fn upgrade(&self, upgrade: Upgrade) -> impl Future<Output = ()> + Send { ... }
    fn name(&self) -> Cow<'static, str> { ... }
}
Expand description

§The building block for Trillium applications.

§Concept

Many other frameworks have a notion of middleware and endpoints, in which the model is that a request passes through a router and then any number of middlewares, then a single endpoint that returns a response, and then passes a response back through the middleware stack.

Because a Trillium Conn represents both a request and response, there is no distinction between middleware and endpoints, as all of these can be modeled as Fn(Conn) -> Future<Output = Conn>.

§Implementing Handler

The simplest handler is an async closure or async fn that receives a Conn and returns a Conn, and Handler has a blanket implementation for any such Fn.

// as a closure
let handler = |conn: trillium::Conn| async move { conn.ok("trillium!") };

let app = TestServer::new(handler).await;
app.get("/").await.assert_ok().assert_body("trillium!");
// as an async function
async fn handler(conn: trillium::Conn) -> trillium::Conn {
    conn.ok("trillium!")
}
let app = TestServer::new(handler).await;
app.get("/").await.assert_ok().assert_body("trillium!");

The simplest implementation of Handler for a named type looks like this:

pub struct MyHandler;
impl trillium::Handler for MyHandler {
    async fn run(&self, conn: trillium::Conn) -> trillium::Conn {
        conn
    }
}

let app = TestServer::new(MyHandler).await;
app.get("/").await.assert_status(404); // we did not halt or set a body status
//

See each of the function definitions below for advanced implementation.

For most application code and even trillium-packaged framework code, run is the only trait function that needs to be implemented.

Provided Methods§

Source

fn run(&self, conn: Conn) -> impl Future<Output = Conn> + Send

Executes this handler, performing any modifications to the Conn that are desired.

Source

fn init(&mut self, info: &mut Info) -> impl Future<Output = ()> + Send

Performs one-time async set up on a mutable borrow of the Handler before the server starts accepting requests. This allows a Handler to be defined in synchronous code but perform async setup such as establishing a database connection or fetching some state from an external source. This is optional, and chances are high that you do not need this.

It also receives a mutable borrow of the Info that represents the current connection.

Source

fn before_send(&self, conn: Conn) -> impl Future<Output = Conn> + Send

Performs any final modifications to this conn after all handlers have been run. Although this is a slight deviation from the simple conn->conn->conn chain represented by most Handlers, it provides an easy way for libraries to effectively inject a second handler into a response chain. This is useful for loggers that need to record information both before and after other handlers have run, as well as database transaction handlers and similar library code.

❗IMPORTANT NOTE FOR LIBRARY AUTHORS: Please note that this will run whether or not the conn was halted before Handler::run was called on a given conn. This means that if you want to make your before_send callback conditional on whether run was called, you need to put a unit type into the conn’s state and check for that.

stability note: I don’t love this for the exact reason that it breaks the simplicity of the conn->conn->model, but it is currently the best compromise between that simplicity and convenience for the application author, who should not have to add two Handlers to achieve an “around” effect.

Source

fn has_upgrade(&self, upgrade: &Upgrade) -> bool

predicate function answering the question of whether this Handler would like to take ownership of the negotiated Upgrade. If this returns true, you must implement Handler::upgrade. The first handler that responds true to this will receive ownership of the trillium::Upgrade in a subsequent call to Handler::upgrade

Source

fn upgrade(&self, upgrade: Upgrade) -> impl Future<Output = ()> + Send

This will only be called if the handler reponds true to Handler::has_upgrade and will only be called once for this upgrade. There is no return value, and this function takes exclusive ownership of the underlying transport once this is called. You can downcast the transport to whatever the source transport type is and perform any non-http protocol communication that has been negotiated. You probably don’t want this unless you’re implementing something like websockets. Please note that for many transports such as TcpStreams, dropping the transport (and therefore the Upgrade) will hang up / disconnect.

Source

fn name(&self) -> Cow<'static, str>

Customize the name of your handler. This is used in Debug implementations. The default is the type name of this handler.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl Handler for &'static str

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

fn name(&self) -> Cow<'static, str>

Source§

impl Handler for ()

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

impl Handler for String

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

fn name(&self) -> Cow<'static, str>

Source§

impl<A, B> Handler for (A, B)
where A: Handler, B: Handler,

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

async fn init(&mut self, info: &mut Info)

Source§

async fn before_send(&self, conn: Conn) -> Conn

Source§

fn has_upgrade(&self, upgrade: &Upgrade) -> bool

Source§

async fn upgrade(&self, upgrade: Upgrade)

Source§

fn name(&self) -> Cow<'static, str>

Source§

impl<A, B, C> Handler for (A, B, C)
where A: Handler, B: Handler, C: Handler,

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

async fn init(&mut self, info: &mut Info)

Source§

async fn before_send(&self, conn: Conn) -> Conn

Source§

fn has_upgrade(&self, upgrade: &Upgrade) -> bool

Source§

async fn upgrade(&self, upgrade: Upgrade)

Source§

fn name(&self) -> Cow<'static, str>

Source§

impl<A, B, C, D> Handler for (A, B, C, D)
where A: Handler, B: Handler, C: Handler, D: Handler,

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

async fn init(&mut self, info: &mut Info)

Source§

async fn before_send(&self, conn: Conn) -> Conn

Source§

fn has_upgrade(&self, upgrade: &Upgrade) -> bool

Source§

async fn upgrade(&self, upgrade: Upgrade)

Source§

fn name(&self) -> Cow<'static, str>

Source§

impl<A, B, C, D, E> Handler for (A, B, C, D, E)
where A: Handler, B: Handler, C: Handler, D: Handler, E: Handler,

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

async fn init(&mut self, info: &mut Info)

Source§

async fn before_send(&self, conn: Conn) -> Conn

Source§

fn has_upgrade(&self, upgrade: &Upgrade) -> bool

Source§

async fn upgrade(&self, upgrade: Upgrade)

Source§

fn name(&self) -> Cow<'static, str>

Source§

impl<A, B, C, D, E, F> Handler for (A, B, C, D, E, F)
where A: Handler, B: Handler, C: Handler, D: Handler, E: Handler, F: Handler,

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

async fn init(&mut self, info: &mut Info)

Source§

async fn before_send(&self, conn: Conn) -> Conn

Source§

fn has_upgrade(&self, upgrade: &Upgrade) -> bool

Source§

async fn upgrade(&self, upgrade: Upgrade)

Source§

fn name(&self) -> Cow<'static, str>

Source§

impl<A, B, C, D, E, F, G> Handler for (A, B, C, D, E, F, G)
where A: Handler, B: Handler, C: Handler, D: Handler, E: Handler, F: Handler, G: Handler,

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

async fn init(&mut self, info: &mut Info)

Source§

async fn before_send(&self, conn: Conn) -> Conn

Source§

fn has_upgrade(&self, upgrade: &Upgrade) -> bool

Source§

async fn upgrade(&self, upgrade: Upgrade)

Source§

fn name(&self) -> Cow<'static, str>

Source§

impl<A, B, C, D, E, F, G, H> Handler for (A, B, C, D, E, F, G, H)
where A: Handler, B: Handler, C: Handler, D: Handler, E: Handler, F: Handler, G: Handler, H: Handler,

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

async fn init(&mut self, info: &mut Info)

Source§

async fn before_send(&self, conn: Conn) -> Conn

Source§

fn has_upgrade(&self, upgrade: &Upgrade) -> bool

Source§

async fn upgrade(&self, upgrade: Upgrade)

Source§

fn name(&self) -> Cow<'static, str>

Source§

impl<A, B, C, D, E, F, G, H, I> Handler for (A, B, C, D, E, F, G, H, I)
where A: Handler, B: Handler, C: Handler, D: Handler, E: Handler, F: Handler, G: Handler, H: Handler, I: Handler,

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

async fn init(&mut self, info: &mut Info)

Source§

async fn before_send(&self, conn: Conn) -> Conn

Source§

fn has_upgrade(&self, upgrade: &Upgrade) -> bool

Source§

async fn upgrade(&self, upgrade: Upgrade)

Source§

fn name(&self) -> Cow<'static, str>

Source§

impl<A, B, C, D, E, F, G, H, I, J> Handler for (A, B, C, D, E, F, G, H, I, J)
where A: Handler, B: Handler, C: Handler, D: Handler, E: Handler, F: Handler, G: Handler, H: Handler, I: Handler, J: Handler,

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

async fn init(&mut self, info: &mut Info)

Source§

async fn before_send(&self, conn: Conn) -> Conn

Source§

fn has_upgrade(&self, upgrade: &Upgrade) -> bool

Source§

async fn upgrade(&self, upgrade: Upgrade)

Source§

fn name(&self) -> Cow<'static, str>

Source§

impl<A, B, C, D, E, F, G, H, I, J, K> Handler for (A, B, C, D, E, F, G, H, I, J, K)
where A: Handler, B: Handler, C: Handler, D: Handler, E: Handler, F: Handler, G: Handler, H: Handler, I: Handler, J: Handler, K: Handler,

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

async fn init(&mut self, info: &mut Info)

Source§

async fn before_send(&self, conn: Conn) -> Conn

Source§

fn has_upgrade(&self, upgrade: &Upgrade) -> bool

Source§

async fn upgrade(&self, upgrade: Upgrade)

Source§

fn name(&self) -> Cow<'static, str>

Source§

impl<A, B, C, D, E, F, G, H, I, J, K, L> Handler for (A, B, C, D, E, F, G, H, I, J, K, L)
where A: Handler, B: Handler, C: Handler, D: Handler, E: Handler, F: Handler, G: Handler, H: Handler, I: Handler, J: Handler, K: Handler, L: Handler,

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

async fn init(&mut self, info: &mut Info)

Source§

async fn before_send(&self, conn: Conn) -> Conn

Source§

fn has_upgrade(&self, upgrade: &Upgrade) -> bool

Source§

async fn upgrade(&self, upgrade: Upgrade)

Source§

fn name(&self) -> Cow<'static, str>

Source§

impl<A, B, C, D, E, F, G, H, I, J, K, L, M> Handler for (A, B, C, D, E, F, G, H, I, J, K, L, M)
where A: Handler, B: Handler, C: Handler, D: Handler, E: Handler, F: Handler, G: Handler, H: Handler, I: Handler, J: Handler, K: Handler, L: Handler, M: Handler,

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

async fn init(&mut self, info: &mut Info)

Source§

async fn before_send(&self, conn: Conn) -> Conn

Source§

fn has_upgrade(&self, upgrade: &Upgrade) -> bool

Source§

async fn upgrade(&self, upgrade: Upgrade)

Source§

fn name(&self) -> Cow<'static, str>

Source§

impl<A, B, C, D, E, F, G, H, I, J, K, L, M, N> Handler for (A, B, C, D, E, F, G, H, I, J, K, L, M, N)
where A: Handler, B: Handler, C: Handler, D: Handler, E: Handler, F: Handler, G: Handler, H: Handler, I: Handler, J: Handler, K: Handler, L: Handler, M: Handler, N: Handler,

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

async fn init(&mut self, info: &mut Info)

Source§

async fn before_send(&self, conn: Conn) -> Conn

Source§

fn has_upgrade(&self, upgrade: &Upgrade) -> bool

Source§

async fn upgrade(&self, upgrade: Upgrade)

Source§

fn name(&self) -> Cow<'static, str>

Source§

impl<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O> Handler for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O)
where A: Handler, B: Handler, C: Handler, D: Handler, E: Handler, F: Handler, G: Handler, H: Handler, I: Handler, J: Handler, K: Handler, L: Handler, M: Handler, N: Handler, O: Handler,

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

async fn init(&mut self, info: &mut Info)

Source§

async fn before_send(&self, conn: Conn) -> Conn

Source§

fn has_upgrade(&self, upgrade: &Upgrade) -> bool

Source§

async fn upgrade(&self, upgrade: Upgrade)

Source§

fn name(&self) -> Cow<'static, str>

Source§

impl<H: Handler> Handler for Option<H>

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

async fn init(&mut self, info: &mut Info)

Source§

async fn before_send(&self, conn: Conn) -> Conn

Source§

fn name(&self) -> Cow<'static, str>

Source§

fn has_upgrade(&self, upgrade: &Upgrade) -> bool

Source§

async fn upgrade(&self, upgrade: Upgrade)

Source§

impl<H: Handler> Handler for Vec<H>

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

async fn init(&mut self, info: &mut Info)

Source§

async fn before_send(&self, conn: Conn) -> Conn

Source§

fn name(&self) -> Cow<'static, str>

Source§

fn has_upgrade(&self, upgrade: &Upgrade) -> bool

Source§

async fn upgrade(&self, upgrade: Upgrade)

Source§

impl<T, E> Handler for Result<T, E>
where T: Handler, E: Handler,

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

async fn init(&mut self, info: &mut Info)

Source§

async fn before_send(&self, conn: Conn) -> Conn

Source§

fn name(&self) -> Cow<'static, str>

Source§

fn has_upgrade(&self, upgrade: &Upgrade) -> bool

Source§

async fn upgrade(&self, upgrade: Upgrade)

Source§

impl<const L: usize, H: Handler> Handler for [H; L]

Source§

async fn run(&self, conn: Conn) -> Conn

Source§

async fn init(&mut self, info: &mut Info)

Source§

async fn before_send(&self, conn: Conn) -> Conn

Source§

fn name(&self) -> Cow<'static, str>

Source§

fn has_upgrade(&self, upgrade: &Upgrade) -> bool

Source§

async fn upgrade(&self, upgrade: Upgrade)

Implementors§

Source§

impl Handler for Status

Source§

impl Handler for BoxedHandler

Source§

impl Handler for Headers

Source§

impl<F, Fut> Handler for Init<F>
where F: FnOnce(Info) -> Fut + Send + Sync + 'static, Fut: Future<Output = Info> + Send + 'static,

Source§

impl<Fun, Fut> Handler for Fun
where Fun: Fn(Conn) -> Fut + Send + Sync + 'static, Fut: Future<Output = Conn> + Send + 'static,

Source§

impl<T: Clone + Send + Sync + 'static> Handler for State<T>