Skip to main content

mini_serve/
handler.rs

1use std::convert::Infallible;
2use std::future::Future;
3use std::pin::Pin;
4use std::sync::Arc;
5
6use hyper::body::{Bytes, Incoming};
7use hyper::{Request, Response};
8use http_body_util::combinators::BoxBody;
9use http_body_util::Full;
10
11use crate::error::ServeError;
12use crate::state::State;
13
14/// The response body type used by all handlers.
15pub type ResponseBody = BoxBody<Bytes, Infallible>;
16
17/// Create a response body from raw bytes.
18pub fn body(bytes: Bytes) -> ResponseBody {
19	BoxBody::new(Full::new(bytes))
20}
21
22/// A request handler that processes an HTTP request and returns a response or error.
23///
24/// Handlers receive the full request (method, path, headers, body) and the app state,
25/// and return either a response or a `ServeError` (which is converted to an HTTP error response).
26pub type Handler<S> = Arc<
27	dyn Fn(Request<Incoming>, State<S>)
28			-> Pin<Box<dyn Future<Output = Result<Response<ResponseBody>, ServeError>> + Send>>
29		+ Send
30		+ Sync,
31>;
32
33/// Wrap an async function to create a handler.
34///
35/// # Example
36///
37/// ```ignore
38/// use mini_serve::handler;
39/// use hyper::StatusCode;
40/// use hyper::body::Bytes;
41///
42/// let h = handler(|req, state| async move {
43///     Ok::<_, mini_serve::ServeError>(
44///         mini_serve::json(StatusCode::OK, &serde_json::json!({"status": "ok"}))
45///     )
46/// });
47/// ```
48pub fn handler<S, F, Fut>(f: F) -> Handler<S>
49where
50	S: Send + Sync + 'static,
51	F: Fn(Request<Incoming>, State<S>) -> Fut + Send + Sync + 'static,
52	Fut: Future<Output = Result<Response<ResponseBody>, ServeError>> + Send + 'static,
53{
54	Arc::new(move |req, state| Box::pin(f(req, state)))
55}