generalize extractor impls for any Into<AppState>

This commit is contained in:
Brent Schroeter 2025-03-25 11:20:24 -07:00
parent 377035ce88
commit b1e31b4026
3 changed files with 25 additions and 15 deletions

View file

@ -68,20 +68,26 @@ pub type AppState = Arc<App>;
#[derive(Clone)]
pub struct ReqwestClient(pub reqwest::Client);
impl FromRef<AppState> for ReqwestClient {
fn from_ref(state: &AppState) -> Self {
ReqwestClient(state.reqwest_client.clone())
impl<S> FromRef<S> for ReqwestClient
where
S: Into<AppState> + Clone,
{
fn from_ref(state: &S) -> Self {
ReqwestClient(Into::<AppState>::into(state.clone()).reqwest_client.clone())
}
}
/// Extractor to automatically obtain a Deadpool database connection
pub struct DbConn(pub Connection);
impl FromRequestParts<AppState> for DbConn {
impl<S> FromRequestParts<S> for DbConn
where
S: Into<AppState> + Clone + Sync,
{
type Rejection = AppError;
async fn from_request_parts(_: &mut Parts, state: &AppState) -> Result<Self, Self::Rejection> {
let conn = state.db_pool.get().await?;
async fn from_request_parts(_: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
let conn = Into::<AppState>::into(state.clone()).db_pool.get().await?;
Ok(Self(conn))
}
}

View file

@ -108,8 +108,11 @@ impl Settings {
}
}
impl FromRef<AppState> for Settings {
fn from_ref(state: &AppState) -> Self {
state.settings.clone()
impl<S> FromRef<S> for Settings
where
S: Into<AppState> + Clone,
{
fn from_ref(state: &S) -> Self {
Into::<AppState>::into(state.clone()).settings.clone()
}
}

View file

@ -53,15 +53,16 @@ impl User {
#[derive(Clone, Debug)]
pub struct CurrentUser(pub User);
impl FromRequestParts<AppState> for CurrentUser {
impl<S> FromRequestParts<S> for CurrentUser
where
S: Into<AppState> + Clone + Sync,
{
type Rejection = AppError;
async fn from_request_parts(
parts: &mut Parts,
state: &AppState,
) -> Result<Self, <Self as FromRequestParts<AppState>>::Rejection> {
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
let state: AppState = state.clone().into();
let auth_info = parts
.extract_with_state::<AuthInfo, AppState>(state)
.extract_with_state::<AuthInfo, AppState>(&state)
.await
.map_err(|_| {
AppError::auth_redirect_from_base_path(state.settings.base_path.clone())