use std::sync::Arc;
use async_trait::async_trait;
use email_address::EmailAddress;
use fistinc_errors::ServiceResult;
use fistinc_paging::{Paging, QueryParams};
use phonenumber::PhoneNumber;
use uuid::Uuid;
use crate::domain::entity::User;
use crate::domain::services::{UserSecurityService, UserService};
use crate::domain::UserRepository;
pub struct UserServiceImpl {
pub repository: Arc<dyn UserRepository>,
pub security: Arc<dyn UserSecurityService>,
}
impl UserServiceImpl {
pub fn new(repository: Arc<dyn UserRepository>, security: Arc<dyn UserSecurityService>) -> Self {
UserServiceImpl { repository, security }
}
}
#[async_trait]
impl UserService for UserServiceImpl {
async fn create(&self, user: User) -> ServiceResult<User> {
let mut user = user.clone();
let hashed_password = self.security.hash(&user.password).await?;
user.password = hashed_password;
self.repository
.create(&user).await?;
Ok(user)
}
async fn users(&self, params: &dyn QueryParams) -> ServiceResult<Paging<User>> {
Ok(
self.repository
.find_all(params).await?
)
}
async fn find_by_id(&self, id: Uuid) -> ServiceResult<Option<User>> {
Ok(
self.repository
.find(id).await?
)
}
async fn find_by_email(&self, email: &EmailAddress) -> ServiceResult<Option<User>> {
Ok(
self.repository
.find_by_email(email).await?
)
}
async fn find_by_phone(&self, phone: &PhoneNumber) -> ServiceResult<Option<User>> {
Ok(
self.repository
.find_by_phone(phone).await?
)
}
async fn update(&self, update: &User) -> ServiceResult<()> {
Ok(
self.repository
.update(update).await?
)
}
async fn delete_by_id(&self, id: Uuid) -> ServiceResult<()> {
Ok(
self.repository
.delete(id).await?
)
}
}