use std::future::Future;
use std::pin::Pin;
use crate::body::{BoxBody, Request};
use crate::into_response::IntoResponse;
pub trait FromRequestParts<S>: Sized {
type Rejection: IntoResponse;
type Future: Future<Output = Result<Self, Self::Rejection>> + Send;
fn from_request_parts(parts: &mut http::request::Parts, state: &S) -> Self::Future;
}
pub trait FromRequest<S, B = BoxBody>: Sized {
type Rejection: IntoResponse;
type Future: Future<Output = Result<Self, Self::Rejection>> + Send;
fn from_request(req: http::Request<B>, state: &S) -> Self::Future;
}
#[derive(Debug, Clone, Copy)]
pub struct State<T>(pub T);
impl<S: Clone + Send + 'static> FromRequestParts<S> for State<S> {
type Rejection = std::convert::Infallible;
type Future = std::future::Ready<Result<Self, Self::Rejection>>;
fn from_request_parts(_parts: &mut http::request::Parts, state: &S) -> Self::Future {
std::future::ready(Ok(State(state.clone())))
}
}
impl<S: Clone + Send + 'static> FromRequest<S, BoxBody> for State<S> {
type Rejection = std::convert::Infallible;
type Future = Pin<Box<dyn Future<Output = Result<Self, Self::Rejection>> + Send>>;
fn from_request(req: Request, state: &S) -> Self::Future {
let state = state.clone();
Box::pin(async move {
let (_parts, _body) = req.into_parts();
Ok(State(state))
})
}
}