use async_trait::async_trait;
use anyhow::Result;
use serde::{Deserialize, Serialize};
use crate::domain::entity::Bucket;
use crate::infrastructure::persistence::{BucketRepository, PaginationParams, PaginatedResult, BucketFilter};
use super::QueryHandler;
#[deprecated(since = "0.2.0", note = "Use QueryHandler<Q> trait instead")]
#[async_trait]
pub trait BucketQuery: Send + Sync {
type Output;
async fn execute(&self) -> Result<Self::Output>;
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GetBucketByIdQuery {
pub id: String,
}
pub struct GetBucketByIdHandler<R: BucketRepository> {
repository: std::sync::Arc<R>,
}
impl<R: BucketRepository> GetBucketByIdHandler<R> {
pub fn new(repository: std::sync::Arc<R>) -> Self {
Self { repository }
}
}
#[async_trait]
impl<R: BucketRepository + 'static> QueryHandler<GetBucketByIdQuery> for GetBucketByIdHandler<R> {
type Output = Option<Bucket>;
async fn handle(&self, query: GetBucketByIdQuery) -> Result<Self::Output> {
self.repository.find_by_id(&query.id).await
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ListBucketQuery {
pub page: u32,
pub per_page: u32,
pub filter_name: Option<String>,
pub filter_slug: Option<String>,
pub filter_description: Option<String>,
pub filter_owner_id: Option<Uuid>,
pub filter_bucket_type: Option<BucketType>,
pub filter_status: Option<BucketStatus>,
pub filter_storage_backend: Option<StorageBackend>,
pub filter_root_path: Option<String>,
pub filter_total_size_bytes: Option<i64>,
pub filter_max_file_size: Option<i64>,
pub filter_enable_cdn: Option<bool>,
pub filter_enable_versioning: Option<bool>,
pub filter_enable_deduplication: Option<bool>,
}
impl Default for ListBucketQuery {
fn default() -> Self {
Self {
page: 1,
per_page: 20,
filter_name: None,
filter_slug: None,
filter_description: None,
filter_owner_id: None,
filter_bucket_type: None,
filter_status: None,
filter_storage_backend: None,
filter_root_path: None,
filter_total_size_bytes: None,
filter_max_file_size: None,
filter_enable_cdn: None,
filter_enable_versioning: None,
filter_enable_deduplication: None,
}
}
}
pub struct ListBucketHandler<R: BucketRepository> {
repository: std::sync::Arc<R>,
}
impl<R: BucketRepository> ListBucketHandler<R> {
pub fn new(repository: std::sync::Arc<R>) -> Self {
Self { repository }
}
}
#[async_trait]
impl<R: BucketRepository + 'static> QueryHandler<ListBucketQuery> for ListBucketHandler<R> {
type Output = PaginatedResult<Bucket>;
async fn handle(&self, query: ListBucketQuery) -> Result<Self::Output> {
let params = PaginationParams::new(query.page, query.per_page);
let filters = BucketFilter {
name: query.filter_name.clone(),
slug: query.filter_slug.clone(),
description: query.filter_description.clone(),
owner_id: query.filter_owner_id.clone(),
bucket_type: query.filter_bucket_type.clone(),
status: query.filter_status.clone(),
storage_backend: query.filter_storage_backend.clone(),
root_path: query.filter_root_path.clone(),
total_size_bytes: query.filter_total_size_bytes.clone(),
max_file_size: query.filter_max_file_size.clone(),
enable_cdn: query.filter_enable_cdn.clone(),
enable_versioning: query.filter_enable_versioning.clone(),
enable_deduplication: query.filter_enable_deduplication.clone(),
..Default::default()
};
if filters.has_filters() {
self.repository.list_with_filters(params, filters).await
} else {
self.repository.list(params).await
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GetBucketBySlugQuery {
pub slug: String,
}
pub struct GetBucketBySlugHandler<R: BucketRepository> {
repository: std::sync::Arc<R>,
}
impl<R: BucketRepository> GetBucketBySlugHandler<R> {
pub fn new(repository: std::sync::Arc<R>) -> Self {
Self { repository }
}
}
#[async_trait]
impl<R: BucketRepository + 'static> QueryHandler<GetBucketBySlugQuery> for GetBucketBySlugHandler<R> {
type Output = Option<Bucket>;
async fn handle(&self, query: GetBucketBySlugQuery) -> Result<Self::Output> {
self.repository.find_by_slug(&query.slug).await
}
}