#[cfg(test)]
mod tests;
mod path;
#[cfg(feature = "serde")]
mod urlencoded;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use crate::extract::FromRequest;
use crate::header::Header;
use crate::request::Request;
use crate::response::{Response, StatusCodeReasonPhrase};
use crate::router::PathParams;
use crate::server::ConnectionInfo;
pub use crate::error::IntoResponse;
pub use crate::extract::{Body, BodyText, RequestHeaders, RequestId};
#[cfg(feature = "serde")]
pub use crate::json::Json;
pub use path::{FromPath, Path};
pub struct RequestParts<'a, S> {
pub request: &'a Request,
pub params: &'a PathParams,
pub connection: &'a ConnectionInfo,
pub state: &'a Arc<S>,
pub path_names: &'static [&'static str],
}
pub trait FromRequestParts<S>: Sized {
fn from_request_parts(parts: &RequestParts<'_, S>) -> Result<Self, Response>;
}
impl<S, T: FromRequest> FromRequestParts<S> for T {
fn from_request_parts(parts: &RequestParts<'_, S>) -> Result<Self, Response> {
T::from_request(parts.request)
}
}
pub struct State<S>(pub Arc<S>);
impl<S> Clone for State<S> {
fn clone(&self) -> Self {
State(Arc::clone(&self.0))
}
}
impl<S> std::ops::Deref for State<S> {
type Target = S;
fn deref(&self) -> &S {
&self.0
}
}
impl<S> FromRequestParts<S> for State<S> {
fn from_request_parts(parts: &RequestParts<'_, S>) -> Result<Self, Response> {
Ok(State(Arc::clone(parts.state)))
}
}
#[cfg(feature = "serde")]
pub use urlencoded::{Form, Query};
pub trait RouteSpec {
const METHOD: &'static str;
const PATTERN: &'static str;
}
pub trait Handler<S>: RouteSpec + Send + Sync + 'static {
fn handle(&self, request: &Request, params: &PathParams, connection: &ConnectionInfo, state: &Arc<S>) -> Response;
}
pub type HandlerFuture = Pin<Box<dyn Future<Output = Response> + Send + 'static>>;
pub trait AsyncHandler<S>: RouteSpec + Send + Sync + 'static {
fn handle_async(&self, request: Request, params: PathParams, connection: ConnectionInfo, state: Arc<S>) -> HandlerFuture;
}
pub(crate) fn rejection(request: &Request, status: &StatusCodeReasonPhrase, detail: &str) -> Response {
crate::error::problem::with_headers(status, detail, detail, Some(Header::get_header_list(request)))
}
#[doc(hidden)]
pub mod __private {
pub use super::path::{parse_param, path_fits};
#[cfg(feature = "serde")]
pub use super::urlencoded::fuzz as fuzz_urlencoded;
#[inline]
pub fn respond<R: crate::error::IntoResponse>(value: R) -> crate::response::Response {
value.into_response()
}
}