Files
warren/backend/src/lib/domain/warren/service/warren.rs
2025-07-30 23:35:30 +02:00

339 lines
10 KiB
Rust

use crate::domain::warren::{
models::{
file::FileStream,
warren::{
CreateWarrenError, CreateWarrenRequest, DeleteWarrenError, DeleteWarrenRequest,
EditWarrenError, EditWarrenRequest, FetchWarrensError, FetchWarrensRequest,
ListWarrensError, ListWarrensRequest, WarrenCatError, WarrenCatRequest, WarrenCpError,
WarrenCpRequest, WarrenCpResponse, WarrenLsResponse, WarrenMkdirResponse,
WarrenMvError, WarrenMvRequest, WarrenMvResponse, WarrenRmRequest, WarrenRmResponse,
WarrenSaveResponse, WarrenTouchError, WarrenTouchRequest, WarrenTouchResponse,
},
},
ports::FileSystemService,
};
use super::{
super::models::warren::{
FetchWarrenError, FetchWarrenRequest, Warren, WarrenLsError, WarrenLsRequest,
WarrenMkdirError, WarrenMkdirRequest, WarrenRmError, WarrenSaveError, WarrenSaveRequest,
},
super::ports::{WarrenMetrics, WarrenNotifier, WarrenRepository, WarrenService},
};
#[derive(Debug, Clone)]
pub struct Service<R, M, N, FSS>
where
R: WarrenRepository,
M: WarrenMetrics,
N: WarrenNotifier,
FSS: FileSystemService,
{
repository: R,
metrics: M,
notifier: N,
fs_service: FSS,
}
impl<R, M, N, FSS> Service<R, M, N, FSS>
where
R: WarrenRepository,
M: WarrenMetrics,
N: WarrenNotifier,
FSS: FileSystemService,
{
pub fn new(repository: R, metrics: M, notifier: N, fs_service: FSS) -> Self {
Self {
repository,
metrics,
notifier,
fs_service,
}
}
}
impl<R, M, N, FSS> WarrenService for Service<R, M, N, FSS>
where
R: WarrenRepository,
M: WarrenMetrics,
N: WarrenNotifier,
FSS: FileSystemService,
{
async fn create_warren(
&self,
request: CreateWarrenRequest,
) -> Result<Warren, CreateWarrenError> {
let result = self.repository.create_warren(request).await;
if let Ok(warren) = result.as_ref() {
self.metrics.record_warren_creation_success().await;
self.notifier.warren_created(warren).await;
} else {
self.metrics.record_warren_creation_failure().await;
}
result
}
async fn edit_warren(&self, request: EditWarrenRequest) -> Result<Warren, EditWarrenError> {
let result = self.repository.edit_warren(request).await;
if let Ok(warren) = result.as_ref() {
self.metrics.record_warren_edit_success().await;
self.notifier.warren_edited(warren).await;
} else {
self.metrics.record_warren_edit_failure().await;
}
result
}
async fn delete_warren(
&self,
request: DeleteWarrenRequest,
) -> Result<Warren, DeleteWarrenError> {
let result = self.repository.delete_warren(request).await;
if let Ok(warren) = result.as_ref() {
self.metrics.record_warren_deletion_success().await;
self.notifier.warren_deleted(warren).await;
} else {
self.metrics.record_warren_deletion_failure().await;
}
result
}
async fn fetch_warrens(
&self,
request: FetchWarrensRequest,
) -> Result<Vec<Warren>, FetchWarrensError> {
let result = self.repository.fetch_warrens(request).await;
if let Ok(warren) = result.as_ref() {
self.metrics.record_warrens_fetch_success().await;
self.notifier.warrens_fetched(warren).await;
} else {
self.metrics.record_warrens_fetch_failure().await;
}
result
}
async fn list_warrens(
&self,
request: ListWarrensRequest,
) -> Result<Vec<Warren>, ListWarrensError> {
let result = self.repository.list_warrens(request).await;
if let Ok(warren) = result.as_ref() {
self.metrics.record_warren_list_success().await;
self.notifier.warrens_listed(warren).await;
} else {
self.metrics.record_warren_list_failure().await;
}
result
}
async fn fetch_warren(&self, request: FetchWarrenRequest) -> Result<Warren, FetchWarrenError> {
let result = self.repository.fetch_warren(request).await;
if let Ok(warren) = result.as_ref() {
self.metrics.record_warren_fetch_success().await;
self.notifier.warren_fetched(warren).await;
} else {
self.metrics.record_warren_fetch_failure().await;
}
result
}
async fn warren_cat(&self, request: WarrenCatRequest) -> Result<FileStream, WarrenCatError> {
let warren = self.repository.fetch_warren((&request).into()).await?;
let path = request.base().path().clone();
let cat_request = request.build_fs_request(&warren);
let result = self.fs_service.cat(cat_request).await.map_err(Into::into);
if result.is_ok() {
self.metrics.record_warren_cat_success().await;
self.notifier.warren_cat(&warren, &path).await;
} else {
self.metrics.record_warren_cat_failure().await;
}
result
}
async fn warren_ls(&self, request: WarrenLsRequest) -> Result<WarrenLsResponse, WarrenLsError> {
let warren = self.repository.fetch_warren(request.clone().into()).await?;
let path = request.base().path().clone();
let ls_request = request.build_fs_request(&warren);
let result = self
.fs_service
.ls(ls_request)
.await
.map(|files| WarrenLsResponse::new(warren, path, files))
.map_err(Into::into);
if let Ok(response) = result.as_ref() {
self.metrics.record_warren_ls_success().await;
self.notifier.warren_ls(response).await;
} else {
self.metrics.record_warren_ls_failure().await;
}
result
}
async fn warren_mkdir(
&self,
request: WarrenMkdirRequest,
) -> Result<WarrenMkdirResponse, WarrenMkdirError> {
let warren = self.repository.fetch_warren(request.clone().into()).await?;
let path = request.base().path().clone();
let mkdir_request = request.build_fs_request(&warren);
let result = self
.fs_service
.mkdir(mkdir_request)
.await
.map(|_| WarrenMkdirResponse::new(warren, path))
.map_err(Into::into);
if let Ok(response) = result.as_ref() {
self.metrics.record_warren_mkdir_success().await;
self.notifier.warren_mkdir(response).await;
} else {
self.metrics.record_warren_mkdir_failure().await;
}
result
}
async fn warren_save<'s>(
&self,
request: WarrenSaveRequest<'s>,
) -> Result<WarrenSaveResponse, WarrenSaveError> {
let warren = self.repository.fetch_warren((&request).into()).await?;
let path = request.base().path().clone();
let save_request = request.build_fs_request(&warren);
let result = self
.fs_service
.save(save_request)
.await
.map(|base| WarrenSaveResponse::new(warren, path, base))
.map_err(Into::into);
if let Ok(result) = result.as_ref() {
self.metrics.record_warren_save_success().await;
self.notifier
.warren_save(result.warren(), result.path())
.await;
} else {
self.metrics.record_warren_save_failure().await;
}
result
}
async fn warren_rm(&self, request: WarrenRmRequest) -> Result<WarrenRmResponse, WarrenRmError> {
let warren = self.repository.fetch_warren((&request).into()).await?;
let path = request.base().path().clone();
let rm_request = request.build_fs_request(&warren);
let result = self
.fs_service
.rm(rm_request)
.await
.map(|_| WarrenRmResponse::new(warren, path))
.map_err(Into::into);
if let Ok(response) = result.as_ref() {
self.metrics.record_warren_rm_success().await;
self.notifier.warren_rm(response).await;
} else {
self.metrics.record_warren_rm_failure().await;
}
result
}
async fn warren_mv(&self, request: WarrenMvRequest) -> Result<WarrenMvResponse, WarrenMvError> {
let warren = self.repository.fetch_warren((&request).into()).await?;
let old_path = request.base().path().clone();
let new_path = request.base().target_path().clone();
let mv_request = request.build_fs_request(&warren);
let result = self
.fs_service
.mv(mv_request)
.await
.map(|_| WarrenMvResponse::new(warren, old_path, new_path))
.map_err(Into::into);
if let Ok(response) = result.as_ref() {
self.metrics.record_warren_mv_success().await;
self.notifier.warren_mv(response).await;
} else {
self.metrics.record_warren_mv_failure().await;
}
result
}
async fn warren_touch(
&self,
request: WarrenTouchRequest,
) -> Result<WarrenTouchResponse, WarrenTouchError> {
let warren = self.repository.fetch_warren((&request).into()).await?;
let path = request.base().path().clone();
let touch_request = request.build_fs_request(&warren);
let result = self
.fs_service
.touch(touch_request)
.await
.map(|_| WarrenTouchResponse::new(warren, path))
.map_err(Into::into);
if let Ok(response) = result.as_ref() {
self.metrics.record_warren_touch_success().await;
self.notifier
.warren_touch(response.warren(), response.path())
.await;
} else {
self.metrics.record_warren_touch_failure().await;
}
result
}
async fn warren_cp(&self, request: WarrenCpRequest) -> Result<WarrenCpResponse, WarrenCpError> {
let warren = self.repository.fetch_warren((&request).into()).await?;
let cp_request = request.build_fs_request(&warren);
let result = self
.fs_service
.cp(cp_request)
.await
.map(|base| WarrenCpResponse::new(warren, base))
.map_err(Into::into);
if let Ok(response) = result.as_ref() {
self.metrics.record_warren_cp_success().await;
self.notifier.warren_cp(response).await;
} else {
self.metrics.record_warren_cp_failure().await;
}
result
}
}