From 5b3c2d4ec7cd07f1b1ec45a742df767ca6080f0f Mon Sep 17 00:00:00 2001 From: Rorik Star Platinum Date: Wed, 5 Nov 2025 00:47:34 +0300 Subject: [PATCH] (refactor) AppState to state mod --- src/api.rs | 4 ++++ src/api/banking.rs | 46 +++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 20 ++++++++----------- src/route.rs | 2 +- src/route/handlers.rs | 2 +- src/state.rs | 32 ++++++++++++++++++++++++++++++ 6 files changed, 92 insertions(+), 14 deletions(-) create mode 100644 src/api.rs create mode 100644 src/api/banking.rs create mode 100644 src/state.rs diff --git a/src/api.rs b/src/api.rs new file mode 100644 index 0000000..411315a --- /dev/null +++ b/src/api.rs @@ -0,0 +1,4 @@ +// src/api.rs +// Объявляет клиенты для работы с внешними API + +pub mod banking; // Наш HTTP клиент к банковским API diff --git a/src/api/banking.rs b/src/api/banking.rs new file mode 100644 index 0000000..178f1e9 --- /dev/null +++ b/src/api/banking.rs @@ -0,0 +1,46 @@ +// src/api/banking.rs + +use reqwest::Client as HttpClient; +use std::sync::Arc; + +// Модели и ошибки можно вынести в отдельные файлы в api/ +// Например, api/banking_models.rs + +#[derive(Debug, serde::Deserialize)] +pub struct BankToken { + pub access_token: String, + pub expires_in: i64, +} + +#[derive(Debug, Clone, Copy)] +pub enum Bank { + VBank, + ABank, + SBank, +} + +impl Bank { + // ... +} + +#[derive(Clone)] +pub struct BankClient { + // ... +} + +impl BankClient { + // ... +} + +#[derive(Clone)] +pub struct BankingClients { + pub vbank: BankClient, + pub abank: BankClient, + pub sbank: BankClient, +} + +impl BankingClients { + pub async fn new() -> Self { + // ... + } +} diff --git a/src/main.rs b/src/main.rs index 898ac0e..b9fc884 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,28 +1,24 @@ // src/main.rs -mod route; // Объявляем модуль route (это либо route.rs, либо route/mod.rs) -mod db; // Объявляем модуль для работы с БД +mod route; +mod db; +mod state; +mod api; use std::net::SocketAddr; -use sqlx::PgPool; +use api::banking::BankingClients; + + /// Общее состояние приложения, передаётся во все handlers /// Это паттерн Axum: State используется в extract'ах -#[derive(Clone)] -pub struct AppState { - pub db_pool: PgPool, -} #[tokio::main] async fn main() { // 1. Загружаем переменные окружения из .env или secrets (через sops) dotenvy::dotenv().ok(); - // 2. Инициализируем базу данных - let db_pool = db::init_pool().await; - println!("✅ Database connection pool created successfully."); - // 3. Создаём общее состояние приложения - let app_state = AppState { db_pool }; + let app_state = AppState::new().await; // 4. Конфигурируем роуты (все роуты централизованы в route::router()) let app = route::router(app_state); diff --git a/src/route.rs b/src/route.rs index b881ee9..41492e7 100644 --- a/src/route.rs +++ b/src/route.rs @@ -7,7 +7,7 @@ pub mod handlers; // Объявляем подмодуль handlers use axum::{routing::get, Router}; -use crate::AppState; +use crate::state::AppState; /// Создаёт и возвращает Router со всеми сконфигурированными роутами /// Функция принимает AppState и передаёт его всем handlers'ам diff --git a/src/route/handlers.rs b/src/route/handlers.rs index baaac4f..f06f0e8 100644 --- a/src/route/handlers.rs +++ b/src/route/handlers.rs @@ -10,7 +10,7 @@ use axum::{ Json, }; use serde_json::json; -use crate::AppState; +use crate::state::AppState; /// Health-check handler /// diff --git a/src/state.rs b/src/state.rs new file mode 100644 index 0000000..d44af75 --- /dev/null +++ b/src/state.rs @@ -0,0 +1,32 @@ +// src/state.rs +// Ответственность: создание и управление общим состоянием приложения (AppState) + +use crate::db; +use crate::api::banking::BankingClients; +use sqlx::PgPool; + +/// Общее состояние приложения, доступное во всех handlers +#[derive(Clone)] +pub struct AppState { + pub db_pool: PgPool, + pub banking_clients: BankingClients, +} + +impl AppState { + /// Асинхронный конструктор для AppState + /// + /// Инициализирует все необходимые ресурсы (пул БД, HTTP клиенты) + /// и собирает их в единый стейт. + pub async fn new() -> Self { + let db_pool = db::init_pool().await; + println!("✅ Database connection pool created successfully."); + + let banking_clients = BankingClients::new().await; + println!("✅ Banking API clients initialized."); + + Self { + db_pool, + banking_clients, + } + } +}