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]>);