From 5618da7d37b986de6659150241cec11cf220d0ad Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Sat, 16 May 2026 11:19:04 +0200 Subject: [PATCH] refactor(presentation): replace impl FromAppState boilerplate with deps_struct! macro in remaining handlers --- crates/presentation/src/handlers/api_keys.rs | 19 +++------ crates/presentation/src/handlers/auth.rs | 28 ++++--------- .../src/handlers/federation_management.rs | 28 ++++--------- .../src/handlers/notifications.rs | 19 +++------ crates/presentation/src/handlers/social.rs | 40 ++++++------------- 5 files changed, 38 insertions(+), 96 deletions(-) diff --git a/crates/presentation/src/handlers/api_keys.rs b/crates/presentation/src/handlers/api_keys.rs index 61099b8..983b97c 100644 --- a/crates/presentation/src/handlers/api_keys.rs +++ b/crates/presentation/src/handlers/api_keys.rs @@ -1,7 +1,7 @@ use crate::{ + deps_struct, errors::ApiError, - extractors::{AuthUser, Deps, FromAppState}, - state::AppState, + extractors::{AuthUser, Deps}, }; use api_types::{ requests::CreateApiKeyRequest, @@ -14,20 +14,11 @@ use axum::{ Json, }; use domain::{ports::ApiKeyRepository, value_objects::ApiKeyId}; -use std::sync::Arc; use uuid::Uuid; -pub struct ApiKeysDeps { - pub api_keys: Arc, -} - -impl FromAppState for ApiKeysDeps { - fn from_state(s: &AppState) -> Self { - Self { - api_keys: s.api_keys.clone(), - } - } -} +deps_struct!(ApiKeysDeps { + api_keys: ApiKeyRepository, +}); #[utoipa::path(get, path = "/api-keys", responses((status = 200, description = "API keys", body = Vec)), security(("bearer_auth" = [])))] pub async fn get_api_keys( diff --git a/crates/presentation/src/handlers/auth.rs b/crates/presentation/src/handlers/auth.rs index d273c96..ed66332 100644 --- a/crates/presentation/src/handlers/auth.rs +++ b/crates/presentation/src/handlers/auth.rs @@ -1,7 +1,7 @@ use crate::{ + deps_struct, errors::ApiError, - extractors::{Deps, FromAppState}, - state::AppState, + extractors::Deps, }; use api_types::{ requests::{LoginRequest, RegisterRequest}, @@ -10,25 +10,13 @@ use api_types::{ use application::use_cases::auth::{login, register, LoginInput, RegisterInput}; use axum::{http::StatusCode, response::IntoResponse, Json}; use domain::ports::{AuthService, EventPublisher, PasswordHasher, UserRepository}; -use std::sync::Arc; -pub struct AuthDeps { - pub users: Arc, - pub hasher: Arc, - pub auth: Arc, - pub events: Arc, -} - -impl FromAppState for AuthDeps { - fn from_state(s: &AppState) -> Self { - Self { - users: s.users.clone(), - hasher: s.hasher.clone(), - auth: s.auth.clone(), - events: s.events.clone(), - } - } -} +deps_struct!(AuthDeps { + users: UserRepository, + hasher: PasswordHasher, + auth: AuthService, + events: EventPublisher, +}); pub fn to_user_response(u: &domain::models::user::User) -> UserResponse { UserResponse { diff --git a/crates/presentation/src/handlers/federation_management.rs b/crates/presentation/src/handlers/federation_management.rs index 705f2b6..f090c2f 100644 --- a/crates/presentation/src/handlers/federation_management.rs +++ b/crates/presentation/src/handlers/federation_management.rs @@ -1,7 +1,7 @@ use crate::{ + deps_struct, errors::ApiError, - extractors::{AuthUser, Deps, FromAppState}, - state::AppState, + extractors::{AuthUser, Deps}, }; use api_types::responses::{ProfileField, RemoteActorResponse}; use application::use_cases::federation_management::{ @@ -11,7 +11,6 @@ use application::use_cases::federation_management::{ use axum::{http::StatusCode, Json}; use domain::ports::{EventPublisher, FederationActionPort, FollowRepository, UserRepository}; use serde::Deserialize; -use std::sync::Arc; #[derive(Deserialize)] pub struct ActorUrlBody { @@ -23,23 +22,12 @@ pub struct HandleBody { pub handle: String, } -pub struct FederationManagementDeps { - pub federation: Arc, - pub follows: Arc, - pub users: Arc, - pub events: Arc, -} - -impl FromAppState for FederationManagementDeps { - fn from_state(s: &AppState) -> Self { - Self { - federation: s.federation.clone(), - follows: s.follows.clone(), - users: s.users.clone(), - events: s.events.clone(), - } - } -} +deps_struct!(FederationManagementDeps { + federation: FederationActionPort, + follows: FollowRepository, + users: UserRepository, + events: EventPublisher, +}); fn to_response(a: domain::models::remote_actor::RemoteActor) -> RemoteActorResponse { RemoteActorResponse { diff --git a/crates/presentation/src/handlers/notifications.rs b/crates/presentation/src/handlers/notifications.rs index f24b1ee..833cecf 100644 --- a/crates/presentation/src/handlers/notifications.rs +++ b/crates/presentation/src/handlers/notifications.rs @@ -1,7 +1,7 @@ use crate::{ + deps_struct, errors::ApiError, - extractors::{AuthUser, Deps, FromAppState}, - state::AppState, + extractors::{AuthUser, Deps}, }; use api_types::requests::NotificationUpdateRequest; use application::use_cases::notifications::{ @@ -16,20 +16,11 @@ use axum::{ use domain::{ models::feed::PageParams, ports::NotificationRepository, value_objects::NotificationId, }; -use std::sync::Arc; use uuid::Uuid; -pub struct NotificationsDeps { - pub notifications: Arc, -} - -impl FromAppState for NotificationsDeps { - fn from_state(s: &AppState) -> Self { - Self { - notifications: s.notifications.clone(), - } - } -} +deps_struct!(NotificationsDeps { + notifications: NotificationRepository, +}); #[utoipa::path(get, path = "/notifications", responses((status = 200, description = "Notification summary")), security(("bearer_auth" = [])))] pub async fn list_notifications( diff --git a/crates/presentation/src/handlers/social.rs b/crates/presentation/src/handlers/social.rs index 7fbb1bd..9cb9c4b 100644 --- a/crates/presentation/src/handlers/social.rs +++ b/crates/presentation/src/handlers/social.rs @@ -1,7 +1,7 @@ use crate::{ + deps_struct, errors::ApiError, - extractors::{AuthUser, Deps, FromAppState}, - state::AppState, + extractors::{AuthUser, Deps}, }; use api_types::requests::SetTopFriendsRequest; use api_types::responses::TopFriendsResponse; @@ -20,34 +20,18 @@ use domain::{ }, value_objects::{ThoughtId, UserId}, }; -use std::sync::Arc; use uuid::Uuid; -pub struct SocialDeps { - pub likes: Arc, - pub boosts: Arc, - pub follows: Arc, - pub users: Arc, - pub federation: Arc, - pub events: Arc, - pub blocks: Arc, - pub top_friends: Arc, -} - -impl FromAppState for SocialDeps { - fn from_state(s: &AppState) -> Self { - Self { - likes: s.likes.clone(), - boosts: s.boosts.clone(), - follows: s.follows.clone(), - users: s.users.clone(), - federation: s.federation.clone(), - events: s.events.clone(), - blocks: s.blocks.clone(), - top_friends: s.top_friends.clone(), - } - } -} +deps_struct!(SocialDeps { + likes: LikeRepository, + boosts: BoostRepository, + follows: FollowRepository, + users: UserRepository, + federation: FederationActionPort, + events: EventPublisher, + blocks: BlockRepository, + top_friends: TopFriendRepository, +}); #[utoipa::path(post, path = "/thoughts/{id}/like", params(("id" = uuid::Uuid, Path, description = "Thought ID")), responses((status = 204, description = "Liked")), security(("bearer_auth" = [])))] pub async fn post_like(