feat(storage): add generic object storage adapter with CQRS traits, key validation, StorageConfig, and cargo-generate integration
This commit is contained in:
27
crates/presentation/src/handlers/storage_example.rs
Normal file
27
crates/presentation/src/handlers/storage_example.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
// Example: stream a stored file as an HTTP response.
|
||||
// Remove this file or replace with your own handlers.
|
||||
//
|
||||
// To use, add to your router:
|
||||
// .route("/files/*key", get(storage_example::get_file))
|
||||
//
|
||||
// use axum::{
|
||||
// body::Body,
|
||||
// extract::{Path, State},
|
||||
// http::StatusCode,
|
||||
// response::IntoResponse,
|
||||
// };
|
||||
// use futures::StreamExt;
|
||||
// use crate::state::AppState;
|
||||
//
|
||||
// pub async fn get_file(
|
||||
// Path(key): Path<String>,
|
||||
// State(state): State<AppState>,
|
||||
// ) -> Result<impl IntoResponse, StatusCode> {
|
||||
// let stream = state
|
||||
// .storage
|
||||
// .get(&key)
|
||||
// .await
|
||||
// .map_err(|_| StatusCode::NOT_FOUND)?;
|
||||
// let body = Body::from_stream(stream.map(|r| r.map_err(|e| e.to_string())));
|
||||
// Ok(body)
|
||||
// }
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::sync::Arc;
|
||||
use application::use_cases::{GetProfile, LoginUser, RegisterUser};
|
||||
use domain::ports::TokenIssuer;
|
||||
use domain::ports::{StoragePort, TokenIssuer};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
@@ -8,6 +8,9 @@ pub struct AppState {
|
||||
pub login_uc: Arc<LoginUser>,
|
||||
pub get_profile_uc: Arc<GetProfile>,
|
||||
pub token_issuer: Arc<dyn TokenIssuer>,
|
||||
/// Direct storage access for handlers. Use cases that need storage should receive
|
||||
/// `Arc<dyn StoragePort>` in their own constructor rather than reading it from `AppState`.
|
||||
pub storage: Arc<dyn StoragePort>,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
@@ -16,7 +19,8 @@ impl AppState {
|
||||
login_uc: Arc<LoginUser>,
|
||||
get_profile_uc: Arc<GetProfile>,
|
||||
token_issuer: Arc<dyn TokenIssuer>,
|
||||
storage: Arc<dyn StoragePort>,
|
||||
) -> Self {
|
||||
Self { register_uc, login_uc, get_profile_uc, token_issuer }
|
||||
Self { register_uc, login_uc, get_profile_uc, token_issuer, storage }
|
||||
}
|
||||
}
|
||||
|
||||
28
crates/presentation/src/state.rs.liquid
Normal file
28
crates/presentation/src/state.rs.liquid
Normal file
@@ -0,0 +1,28 @@
|
||||
use std::sync::Arc;
|
||||
use application::use_cases::{GetProfile, LoginUser, RegisterUser};
|
||||
{% if storage %}
|
||||
use domain::ports::{StoragePort, TokenIssuer};
|
||||
{% else %}
|
||||
use domain::ports::TokenIssuer;
|
||||
{% endif %}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
pub register_uc: Arc<RegisterUser>,
|
||||
pub login_uc: Arc<LoginUser>,
|
||||
pub get_profile_uc: Arc<GetProfile>,
|
||||
pub token_issuer: Arc<dyn TokenIssuer>,
|
||||
{% if storage %}pub storage: Arc<dyn StoragePort>,{% endif %}
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
pub fn new(
|
||||
register_uc: Arc<RegisterUser>,
|
||||
login_uc: Arc<LoginUser>,
|
||||
get_profile_uc: Arc<GetProfile>,
|
||||
token_issuer: Arc<dyn TokenIssuer>,
|
||||
{% if storage %}storage: Arc<dyn StoragePort>,{% endif %}
|
||||
) -> Self {
|
||||
Self { register_uc, login_uc, get_profile_uc, token_issuer{% if storage %}, storage{% endif %} }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user