use async_trait::async_trait;
use anyhow::Result;
use serde::{Deserialize, Serialize};
use crate::domain::entity::ContentHash;
use crate::infrastructure::persistence::{ContentHashRepository, PaginationParams, PaginatedResult, ContentHashFilter};
use super::QueryHandler;
#[deprecated(since = "0.2.0", note = "Use QueryHandler<Q> trait instead")]
#[async_trait]
pub trait ContentHashQuery: Send + Sync {
type Output;
async fn execute(&self) -> Result<Self::Output>;
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GetContentHashByIdQuery {
pub id: String,
}
pub struct GetContentHashByIdHandler<R: ContentHashRepository> {
repository: std::sync::Arc<R>,
}
impl<R: ContentHashRepository> GetContentHashByIdHandler<R> {
pub fn new(repository: std::sync::Arc<R>) -> Self {
Self { repository }
}
}
#[async_trait]
impl<R: ContentHashRepository + 'static> QueryHandler<GetContentHashByIdQuery> for GetContentHashByIdHandler<R> {
type Output = Option<ContentHash>;
async fn handle(&self, query: GetContentHashByIdQuery) -> Result<Self::Output> {
self.repository.find_by_id(&query.id).await
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ListContentHashQuery {
pub page: u32,
pub per_page: u32,
pub filter_hash: Option<String>,
pub filter_size_bytes: Option<i64>,
pub filter_storage_key: Option<String>,
pub filter_storage_backend: Option<StorageBackend>,
pub filter_fingerprint: Option<String>,
}
impl Default for ListContentHashQuery {
fn default() -> Self {
Self {
page: 1,
per_page: 20,
filter_hash: None,
filter_size_bytes: None,
filter_storage_key: None,
filter_storage_backend: None,
filter_fingerprint: None,
}
}
}
pub struct ListContentHashHandler<R: ContentHashRepository> {
repository: std::sync::Arc<R>,
}
impl<R: ContentHashRepository> ListContentHashHandler<R> {
pub fn new(repository: std::sync::Arc<R>) -> Self {
Self { repository }
}
}
#[async_trait]
impl<R: ContentHashRepository + 'static> QueryHandler<ListContentHashQuery> for ListContentHashHandler<R> {
type Output = PaginatedResult<ContentHash>;
async fn handle(&self, query: ListContentHashQuery) -> Result<Self::Output> {
let params = PaginationParams::new(query.page, query.per_page);
let filters = ContentHashFilter {
hash: query.filter_hash.clone(),
size_bytes: query.filter_size_bytes.clone(),
storage_key: query.filter_storage_key.clone(),
storage_backend: query.filter_storage_backend.clone(),
fingerprint: query.filter_fingerprint.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 GetContentHashByHashQuery {
pub hash: String,
}
pub struct GetContentHashByHashHandler<R: ContentHashRepository> {
repository: std::sync::Arc<R>,
}
impl<R: ContentHashRepository> GetContentHashByHashHandler<R> {
pub fn new(repository: std::sync::Arc<R>) -> Self {
Self { repository }
}
}
#[async_trait]
impl<R: ContentHashRepository + 'static> QueryHandler<GetContentHashByHashQuery> for GetContentHashByHashHandler<R> {
type Output = Option<ContentHash>;
async fn handle(&self, query: GetContentHashByHashQuery) -> Result<Self::Output> {
self.repository.find_by_hash(&query.hash).await
}
}