lab_resource_manager/application/usecases/
create_resource_usage.rs1use crate::application::error::ApplicationError;
2use crate::domain::aggregates::resource_usage::{
3 entity::ResourceUsage,
4 value_objects::{Resource, TimePeriod, UsageId},
5};
6use crate::domain::common::EmailAddress;
7use crate::domain::ports::repositories::ResourceUsageRepository;
8use crate::domain::services::ResourceConflictChecker;
9use std::sync::Arc;
10
11pub struct CreateResourceUsageUseCase<R: ResourceUsageRepository> {
13 repository: Arc<R>,
14 conflict_checker: ResourceConflictChecker,
15}
16
17impl<R: ResourceUsageRepository> CreateResourceUsageUseCase<R> {
18 pub fn new(repository: Arc<R>) -> Self {
23 let conflict_checker = ResourceConflictChecker::new();
24 Self {
25 repository,
26 conflict_checker,
27 }
28 }
29
30 pub async fn execute(
45 &self,
46 owner_email: EmailAddress,
47 time_period: TimePeriod,
48 resources: Vec<Resource>,
49 notes: Option<String>,
50 ) -> Result<UsageId, ApplicationError> {
51 self.conflict_checker
53 .check_conflicts(self.repository.as_ref(), &time_period, &resources, None)
54 .await
55 .map_err(|e| match e {
56 crate::domain::services::resource_usage::errors::ConflictCheckError::Conflict(
57 conflict_err,
58 ) => ApplicationError::ResourceConflict {
59 resource_description: conflict_err.resource_description.clone(),
60 conflicting_usage_id: conflict_err.conflicting_usage_id.as_str().to_string(),
61 },
62 crate::domain::services::resource_usage::errors::ConflictCheckError::Repository(
63 repo_err,
64 ) => ApplicationError::Repository(repo_err),
65 })?;
66
67 let usage = ResourceUsage::new(owner_email, time_period, resources, notes)?;
69
70 self.repository.save(&usage).await?;
72
73 Ok(usage.id().clone())
75 }
76}