use std::sync::Arc;
use super::user::DbUserRepository;
use crate::databases::database::{Database, Error as DatabaseError, Error};
use crate::errors::ServiceError;
use crate::models::torrent_tag::{TagId, TorrentTag};
use crate::models::user::UserId;
pub struct Service {
tag_repository: Arc<DbTagRepository>,
user_repository: Arc<DbUserRepository>,
}
impl Service {
#[must_use]
pub fn new(tag_repository: Arc<DbTagRepository>, user_repository: Arc<DbUserRepository>) -> Service {
Service {
tag_repository,
user_repository,
}
}
pub async fn add_tag(&self, tag_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.tag_repository.add(tag_name).await {
Ok(_) => Ok(()),
Err(e) => match e {
DatabaseError::TagAlreadyExists => Err(ServiceError::TagAlreadyExists),
_ => Err(ServiceError::DatabaseError),
},
}
}
pub async fn delete_tag(&self, tag_id: &TagId, user_id: &UserId) -> Result<(), ServiceError> {
let user = self.user_repository.get_compact(user_id).await?;
if !user.administrator {
return Err(ServiceError::Unauthorized);
}
match self.tag_repository.delete(tag_id).await {
Ok(_) => Ok(()),
Err(e) => match e {
DatabaseError::TagNotFound => Err(ServiceError::TagNotFound),
_ => Err(ServiceError::DatabaseError),
},
}
}
}
pub struct DbTagRepository {
database: Arc<Box<dyn Database>>,
}
impl DbTagRepository {
#[must_use]
pub fn new(database: Arc<Box<dyn Database>>) -> Self {
Self { database }
}
pub async fn add(&self, tag_name: &str) -> Result<(), Error> {
self.database.add_tag(tag_name).await
}
pub async fn get_all(&self) -> Result<Vec<TorrentTag>, Error> {
self.database.get_tags().await
}
pub async fn delete(&self, tag_id: &TagId) -> Result<(), Error> {
self.database.delete_tag(*tag_id).await
}
}