gotham/handler/
mod.rs

1//! Defines types for handlers, the primary building block of a Gotham application.
2//!
3//! A function can be used directly as a handler using one of the default implementations of
4//! `Handler`, but the traits can also be implemented directly for greater control. See the
5//! `Handler` trait for some examples of valid handlers.
6use std::borrow::Cow;
7use std::future::Future;
8use std::ops::Deref;
9use std::panic::RefUnwindSafe;
10use std::pin::Pin;
11use std::sync::Arc;
12
13use bytes::Bytes;
14use futures_util::future::{self, FutureExt};
15use hyper::{Body, Response, StatusCode};
16use mime::{self, Mime};
17
18use crate::helpers::http::response;
19use crate::state::State;
20
21mod assets;
22pub use assets::*;
23
24mod error;
25pub use error::{HandlerError, MapHandlerError, MapHandlerErrorFuture};
26
27/// A type alias for the results returned by async fns that can be passed to to_async.
28pub type HandlerResult = std::result::Result<(State, Response<Body>), (State, HandlerError)>;
29
30/// A type alias for the results returned by async fns that can be passed to to_async_borrowing.
31pub type SimpleHandlerResult = std::result::Result<Response<Body>, HandlerError>;
32
33/// A type alias for the trait objects returned by `HandlerService`.
34///
35/// When the `Future` resolves to an error, the `(State, HandlerError)` value is used to generate
36/// an appropriate HTTP error response.
37pub type HandlerFuture = dyn Future<Output = HandlerResult> + Send;
38
39/// A `Handler` is an asynchronous function, taking a `State` value which represents the request
40/// and related runtime state, and returns a future which resolves to a response.
41///
42/// This represents the common entry point for the parts of a Gotham application, and is used with
43/// the `Router` API to describe how a request should be dispatched and handled.
44///
45/// The `Handler` is created and consumed by each request. In the most common case (a bare function
46/// acting as a `Handler`) the `Handler + Copy` traits allow the `Handler` to be copied for each
47/// request, and the copy consumed. For a closure or a custom handler, the `NewHandler`
48/// implementation creates a `Handler` value for each request.
49///
50/// # Examples
51///
52/// The simplest kind of handler is a bare function which returns a synchronous response. This is
53/// useful when we don't need to do any I/O before generating a response.
54///
55/// ```rust
56/// # extern crate gotham;
57/// # extern crate hyper;
58/// #
59/// # use hyper::{Body, Response};
60/// # use gotham::handler::Handler;
61/// # use gotham::state::State;
62/// #
63/// # fn main() {
64/// fn my_handler(_state: State) -> (State, Response<Body>) {
65///     // Implementation elided.
66/// #   unimplemented!()
67/// }
68/// #
69/// # fn assert_type<H>(_h: H) where H: Handler + Copy {}
70/// # assert_type(my_handler);
71/// # }
72/// ```
73///
74/// An asynchronous handler returns a `HandlerFuture` that will resolve to the response. For
75/// example, this allows I/O work to begin, and for the Gotham app to continue generating a
76/// response once the work completes.
77///
78/// ```rust
79/// # extern crate gotham;
80/// # extern crate hyper;
81/// #
82/// # use std::pin::Pin;
83/// #
84/// # use gotham::handler::{Handler, HandlerFuture};
85/// # use gotham::state::State;
86/// #
87/// # fn main() {
88/// fn async_handler(_state: State) -> Pin<Box<HandlerFuture>> {
89///     // Implementation elided.
90/// #   unimplemented!()
91/// }
92/// #
93/// # fn assert_type<H>(_h: H) where H: Handler + Copy {}
94/// # assert_type(async_handler);
95/// # }
96/// ```
97///
98/// A closure can implement `Handler` automatically, in the same way as a bare function. When
99/// constructing a `Handler` in this way, a wrapping closure must also be used to implement the
100/// `NewHandler` trait.
101///
102/// ```rust
103/// # use gotham::handler::{NewHandler, IntoHandlerFuture};
104/// # use gotham::helpers::http::response::create_empty_response;
105/// # use gotham::state::State;
106/// # use hyper::StatusCode;
107/// #
108/// # fn main() {
109/// let new_handler = || {
110///     let handler = |state: State| {
111///         // Implementation elided.
112/// #       let res = create_empty_response(&state, StatusCode::OK);
113/// #       (state, res).into_handler_future()
114///     };
115///     Ok(handler)
116/// };
117///
118/// // Pass `new_handler` to the router, using the `to_new_handler` API.
119/// #
120/// # fn assert_type<H>(_h: H) where H: NewHandler {}
121/// # assert_type(new_handler);
122/// # }
123/// ```
124///
125/// A custom handler, which implements the `NewHandler` and `Handler` traits directly for greater
126/// control. See the `NewHandler` trait for more examples of custom handlers.
127///
128/// ```rust
129/// # extern crate gotham;
130/// # extern crate hyper;
131/// #
132/// # use std::pin::Pin;
133/// #
134/// # use gotham::handler::{Handler, HandlerFuture, NewHandler};
135/// # use gotham::state::State;
136/// #
137/// # fn main() {
138/// #[derive(Copy, Clone)]
139/// struct MyCustomHandler;
140///
141/// impl NewHandler for MyCustomHandler {
142///     type Instance = Self;
143///
144///     fn new_handler(&self) -> anyhow::Result<Self::Instance> {
145///         Ok(*self)
146///     }
147/// }
148///
149/// impl Handler for MyCustomHandler {
150///     fn handle(self, _state: State) -> Pin<Box<HandlerFuture>> {
151///         // Implementation elided.
152/// #       unimplemented!()
153///     }
154/// }
155/// #
156/// # fn assert_type<H>(_h: H) where H: NewHandler {}
157/// # assert_type(MyCustomHandler);
158/// # }
159/// ```
160pub trait Handler: Send {
161    /// Handles the request, returning a boxed future which resolves to a response.
162    fn handle(self, state: State) -> Pin<Box<HandlerFuture>>;
163}
164
165impl<F, R> Handler for F
166where
167    F: FnOnce(State) -> R + Send,
168    R: IntoHandlerFuture,
169{
170    fn handle(self, state: State) -> Pin<Box<HandlerFuture>> {
171        self(state).into_handler_future()
172    }
173}
174
175/// A type which is used to spawn new `Handler` values. When implementing a custom `Handler` type,
176/// this is used to define how instances of the `Handler` are created.
177///
178/// The `Instance` associated type is usually `Self` in the simple case, but can be a different
179/// type where greater control is needed over lifetimes.
180///
181/// # Examples
182///
183/// A custom handler which implements `NewHandler` by copying itself.
184///
185/// ```rust
186/// # extern crate gotham;
187/// # extern crate hyper;
188/// #
189/// # use std::pin::Pin;
190/// #
191/// # use gotham::handler::{Handler, HandlerFuture, NewHandler};
192/// # use gotham::state::State;
193/// #
194/// # fn main() {
195/// #[derive(Copy, Clone)]
196/// struct MyCustomHandler;
197///
198/// impl NewHandler for MyCustomHandler {
199///     type Instance = Self;
200///
201///     fn new_handler(&self) -> anyhow::Result<Self::Instance> {
202///         Ok(*self)
203///     }
204/// }
205///
206/// impl Handler for MyCustomHandler {
207///     fn handle(self, _state: State) -> Pin<Box<HandlerFuture>> {
208///         // Implementation elided.
209/// #       unimplemented!()
210///     }
211/// }
212/// #
213/// # fn assert_type<H>(_h: H) where H: NewHandler {}
214/// # assert_type(MyCustomHandler);
215/// # }
216/// ```
217///
218/// A custom handler which implements `NewHandler` using a specific `Instance` type.
219///
220/// ```rust
221/// # extern crate gotham;
222/// # extern crate hyper;
223/// #
224/// # use std::pin::Pin;
225/// #
226/// # use gotham::handler::{Handler, HandlerFuture, NewHandler};
227/// # use gotham::state::State;
228/// #
229/// # fn main() {
230/// #[derive(Copy, Clone)]
231/// struct MyValueInstantiatingHandler;
232///
233/// impl NewHandler for MyValueInstantiatingHandler {
234///     type Instance = MyHandler;
235///
236///     fn new_handler(&self) -> anyhow::Result<Self::Instance> {
237///         Ok(MyHandler)
238///     }
239/// }
240///
241/// struct MyHandler;
242///
243/// impl Handler for MyHandler {
244///     fn handle(self, _state: State) -> Pin<Box<HandlerFuture>> {
245///         // Implementation elided.
246/// #       unimplemented!()
247///     }
248/// }
249/// #
250/// # fn assert_type<H>(_h: H) where H: NewHandler {}
251/// # assert_type(MyValueInstantiatingHandler);
252/// # }
253/// ```
254pub trait NewHandler: Send + Sync + RefUnwindSafe {
255    /// The type of `Handler` created by the `NewHandler`.
256    type Instance: Handler + Send;
257
258    /// Create and return a new `Handler` value.
259    fn new_handler(&self) -> anyhow::Result<Self::Instance>;
260}
261
262impl<F, H> NewHandler for F
263where
264    F: Fn() -> anyhow::Result<H> + Send + Sync + RefUnwindSafe,
265    H: Handler + Send,
266{
267    type Instance = H;
268
269    fn new_handler(&self) -> anyhow::Result<H> {
270        self()
271    }
272}
273
274impl<H> NewHandler for Arc<H>
275where
276    H: NewHandler,
277{
278    type Instance = H::Instance;
279
280    fn new_handler(&self) -> anyhow::Result<Self::Instance> {
281        self.deref().new_handler()
282    }
283}
284
285/// Represents a type which can be converted into the future type returned by a `Handler`.
286///
287/// This is used to allow functions with different return types to satisfy the `Handler` trait
288/// bound via the generic function implementation.
289pub trait IntoHandlerFuture {
290    /// Converts this value into a boxed future resolving to a state and response.
291    fn into_handler_future(self) -> Pin<Box<HandlerFuture>>;
292}
293
294impl<T> IntoHandlerFuture for (State, T)
295where
296    T: IntoResponse,
297{
298    fn into_handler_future(self) -> Pin<Box<HandlerFuture>> {
299        let (state, t) = self;
300        let response = t.into_response(&state);
301        future::ok((state, response)).boxed()
302    }
303}
304
305impl IntoHandlerFuture for Pin<Box<HandlerFuture>> {
306    fn into_handler_future(self) -> Pin<Box<HandlerFuture>> {
307        self
308    }
309}
310
311/// Represents a type which can be converted to a response. This trait is used in converting the
312/// return type of a function into a response.
313///
314/// # Examples
315///
316/// ```rust,no_run
317/// # use gotham::state::State;
318/// # use gotham::handler::IntoResponse;
319/// # use hyper::{Body, Response, StatusCode};
320/// #
321/// struct MyStruct {
322///     value: String,
323/// }
324///
325/// impl MyStruct {
326///     fn new() -> MyStruct {
327///         // ...
328/// #       MyStruct { value: "".to_owned() }
329///     }
330/// }
331///
332/// impl IntoResponse for MyStruct {
333///     fn into_response(self, _state: &State) -> Response<Body> {
334///         Response::builder()
335///             .status(StatusCode::OK)
336///             .body(self.value.into())
337///             .unwrap()
338///     }
339/// }
340///
341/// fn handler(state: State) -> (State, MyStruct) {
342///     (state, MyStruct::new())
343/// }
344///
345/// gotham::start("127.0.0.1:7878", || Ok(handler)).unwrap();
346/// ```
347pub trait IntoResponse {
348    /// Converts this value into a `hyper::Response`
349    fn into_response(self, state: &State) -> Response<Body>;
350}
351
352impl IntoResponse for Response<Body> {
353    fn into_response(self, _state: &State) -> Response<Body> {
354        self
355    }
356}
357
358impl<T, E> IntoResponse for ::std::result::Result<T, E>
359where
360    T: IntoResponse,
361    E: IntoResponse,
362{
363    fn into_response(self, state: &State) -> Response<Body> {
364        match self {
365            Ok(res) => res.into_response(state),
366            Err(e) => e.into_response(state),
367        }
368    }
369}
370
371impl<B> IntoResponse for (Mime, B)
372where
373    B: Into<Body>,
374{
375    fn into_response(self, state: &State) -> Response<Body> {
376        (StatusCode::OK, self.0, self.1).into_response(state)
377    }
378}
379
380impl<B> IntoResponse for (StatusCode, Mime, B)
381where
382    B: Into<Body>,
383{
384    fn into_response(self, state: &State) -> Response<Body> {
385        response::create_response(state, self.0, self.1, self.2)
386    }
387}
388
389// derive IntoResponse for Into<Body> types
390macro_rules! derive_into_response {
391    ($type:ty) => {
392        impl IntoResponse for $type {
393            fn into_response(self, state: &State) -> Response<Body> {
394                (StatusCode::OK, mime::TEXT_PLAIN, self).into_response(state)
395            }
396        }
397    };
398}
399
400// derive Into<Body> types - this is required because we
401// can't impl IntoResponse for Into<Body> due to Response<T>
402// and the potential it will add Into<Body> in the future
403derive_into_response!(Bytes);
404derive_into_response!(String);
405derive_into_response!(Vec<u8>);
406derive_into_response!(&'static str);
407derive_into_response!(&'static [u8]);
408derive_into_response!(Cow<'static, str>);
409derive_into_response!(Cow<'static, [u8]>);