use std::sync::Arc; use async_trait::async_trait; use crate::{ adapter::delivery::{ create_label_request_dto::CreateLabelRequestDto, create_post_request_dto::CreatePostRequestDto, post_info_query_dto::PostQueryDto, update_label_request_dto::UpdateLabelRequestDto, update_post_request_dto::UpdatePostRequestDto, }, application::{ error::post_error::PostError, use_case::{ create_label_use_case::CreateLabelUseCase, create_post_use_case::CreatePostUseCase, get_all_labels_use_case::GetAllLabelsUseCase, get_all_post_info_use_case::GetAllPostInfoUseCase, get_post_by_id_use_case::GetPostByIdUseCase, get_post_by_semantic_id_use_case::GetPostBySemanticIdUseCase, update_label_use_case::UpdateLabelUseCase, update_post_use_case::UpdatePostUseCase, }, }, }; use super::{ label_response_dto::LabelResponseDto, post_info_response_dto::PostInfoResponseDto, post_response_dto::PostResponseDto, }; #[async_trait] pub trait PostController: Send + Sync { async fn get_all_post_info( &self, query: PostQueryDto, user_id: Option, ) -> Result, PostError>; async fn get_post_by_id_or_semantic_id( &self, id_or_semantic_id: &str, user_id: Option, ) -> Result; async fn create_post( &self, post: CreatePostRequestDto, user_id: i32, ) -> Result; async fn update_post( &self, id: i32, post: UpdatePostRequestDto, user_id: i32, ) -> Result; async fn create_label( &self, label: CreateLabelRequestDto, ) -> Result; async fn update_label( &self, id: i32, label: UpdateLabelRequestDto, ) -> Result; async fn get_all_labels(&self) -> Result, PostError>; } pub struct PostControllerImpl { get_all_post_info_use_case: Arc, get_post_by_id_use_case: Arc, get_post_by_semantic_id_use_case: Arc, create_post_use_case: Arc, update_post_use_case: Arc, create_label_use_case: Arc, update_label_use_case: Arc, get_all_labels_use_case: Arc, } impl PostControllerImpl { pub fn new( get_all_post_info_use_case: Arc, get_post_by_id_use_case: Arc, get_post_by_semantic_id_use_case: Arc, create_post_use_case: Arc, update_post_use_case: Arc, create_label_use_case: Arc, update_label_use_case: Arc, get_all_labels_use_case: Arc, ) -> Self { Self { get_all_post_info_use_case, get_post_by_id_use_case, get_post_by_semantic_id_use_case, create_post_use_case, update_post_use_case, create_label_use_case, update_label_use_case, get_all_labels_use_case, } } async fn get_post_by_id( &self, id: i32, user_id: Option, ) -> Result { let result = self.get_post_by_id_use_case.execute(id, user_id).await; result.map(PostResponseDto::from) } async fn get_post_by_semantic_id( &self, semantic_id: &str, user_id: Option, ) -> Result { let result = self .get_post_by_semantic_id_use_case .execute(semantic_id, user_id) .await; result.map(PostResponseDto::from) } } #[async_trait] impl PostController for PostControllerImpl { async fn get_all_post_info( &self, query: PostQueryDto, user_id: Option, ) -> Result, PostError> { let result = self .get_all_post_info_use_case .execute(query.is_published_only.unwrap_or(true), user_id) .await; result.map(|post_info_list| { let post_info_response_dto_list: Vec = post_info_list .into_iter() .map(|post_info| PostInfoResponseDto::from(post_info)) .collect(); post_info_response_dto_list }) } async fn get_post_by_id_or_semantic_id( &self, id_or_semantic_id: &str, user_id: Option, ) -> Result { if let Ok(id) = id_or_semantic_id.parse::() { self.get_post_by_id(id, user_id).await } else { let semantic_id = id_or_semantic_id; self.get_post_by_semantic_id(semantic_id, user_id).await } } async fn create_label( &self, label: CreateLabelRequestDto, ) -> Result { let mut label_entity = label.into_entity(); let id = self .create_label_use_case .execute(label_entity.clone()) .await?; label_entity.id = id; Ok(LabelResponseDto::from(label_entity)) } async fn update_label( &self, id: i32, label: UpdateLabelRequestDto, ) -> Result { let label_entity = label.into_entity(id); self.update_label_use_case .execute(label_entity.clone()) .await?; Ok(LabelResponseDto::from(label_entity)) } async fn get_all_labels(&self) -> Result, PostError> { let result = self.get_all_labels_use_case.execute().await; result.map(|labels| { labels .into_iter() .map(|label| LabelResponseDto::from(label)) .collect() }) } async fn create_post( &self, post: CreatePostRequestDto, user_id: i32, ) -> Result { let label_ids = post.label_ids.clone(); let post_entity = post.into_entity(); let id = self .create_post_use_case .execute(post_entity, &label_ids) .await?; self.get_post_by_id(id, Some(user_id)).await } async fn update_post( &self, id: i32, post: UpdatePostRequestDto, user_id: i32, ) -> Result { let label_ids = post.label_ids.clone(); let post_entity = post.into_entity(id); self.update_post_use_case .execute(post_entity, &label_ids) .await?; self.get_post_by_id(id, Some(user_id)).await } }