use std::sync::Arc;
use super::user::DbUserRepository;
use crate::databases::database::{Category, Database, Error as DatabaseError};
use crate::errors::ServiceError;
use crate::models::category::CategoryId;
use crate::models::user::UserId;
pub struct Service {
category_repository: Arc<DbCategoryRepository>,
user_repository: Arc<DbUserRepository>,
}
impl Service {
#[must_use]
pub fn new(category_repository: Arc<DbCategoryRepository>, user_repository: Arc<DbUserRepository>) -> Service {
Service {
category_repository,
user_repository,
}
}
pub async fn add_category(&self, category_name: &str, user_id: &UserId) -> Result<i64, ServiceError> {
let user = self.user_repository.get_compact(user_id).await?;
if !user.administrator {
return Err(ServiceError::Unauthorized);
}
match self.category_repository.add(category_name).await {
Ok(id) => Ok(id),
Err(e) => match e {
DatabaseError::CategoryAlreadyExists => Err(ServiceError::CategoryAlreadyExists),
_ => Err(ServiceError::DatabaseError),
},
}
}
pub async fn delete_category(&self, category_name: &str, user_id: &UserId) -> Result<(), ServiceError> {
let user = self.user_repository.get_compact(user_id).await?;
if !user.administrator {
return Err(ServiceError::Unauthorized);
}
match self.category_repository.delete(category_name).await {
Ok(_) => Ok(()),
Err(e) => match e {
DatabaseError::CategoryNotFound => Err(ServiceError::CategoryNotFound),
_ => Err(ServiceError::DatabaseError),
},
}
}
}
pub struct DbCategoryRepository {
database: Arc<Box<dyn Database>>,
}
impl DbCategoryRepository {
#[must_use]
pub fn new(database: Arc<Box<dyn Database>>) -> Self {
Self { database }
}
pub async fn get_all(&self) -> Result<Vec<Category>, DatabaseError> {
self.database.get_categories().await
}
pub async fn add(&self, category_name: &str) -> Result<CategoryId, DatabaseError> {
self.database.insert_category_and_get_id(category_name).await
}
pub async fn delete(&self, category_name: &str) -> Result<(), DatabaseError> {
self.database.delete_category(category_name).await
}
pub async fn get_by_name(&self, category_name: &str) -> Result<Category, DatabaseError> {
self.database.get_category_from_name(category_name).await
}
pub async fn get_by_id(&self, category_id: &CategoryId) -> Result<Category, DatabaseError> {
self.database.get_category_from_id(*category_id).await
}
}