use std::sync::Arc;
use http::request::Parts;
use crate::extractors::FromRequest;
use crate::extractors::FromRequestParts;
use crate::responder::Responder;
use crate::state::get_state;
use crate::types::Request;
pub struct State<T>(pub Arc<T>);
impl<T> Clone for State<T> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
#[derive(Debug)]
pub struct MissingState;
impl Responder for MissingState {
fn into_response(self) -> crate::types::Response {
(
http::StatusCode::INTERNAL_SERVER_ERROR,
"missing application state",
)
.into_response()
}
}
impl<'a, T> FromRequest<'a> for State<T>
where
T: Send + Sync + 'static,
{
type Error = MissingState;
fn from_request(
_req: &'a mut Request,
) -> impl core::future::Future<Output = core::result::Result<Self, Self::Error>> + Send + 'a {
futures_util::future::ready(match get_state::<T>() {
Some(arc) => Ok(Self(arc)),
None => Err(MissingState),
})
}
}
impl<'a, T> FromRequestParts<'a> for State<T>
where
T: Send + Sync + 'static,
{
type Error = MissingState;
fn from_request_parts(
_parts: &'a mut Parts,
) -> impl core::future::Future<Output = core::result::Result<Self, Self::Error>> + Send + 'a {
futures_util::future::ready(match get_state::<T>() {
Some(arc) => Ok(Self(arc)),
None => Err(MissingState),
})
}
}