From a46d3007f08342196c55b7738ae759da5dbfeb22 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Wed, 20 Sep 2023 14:10:37 +0100 Subject: [PATCH] refactor: [#276] extract function Torrent::validate_and_build_metadata --- src/databases/database.rs | 2 +- src/databases/mysql.rs | 2 +- src/databases/sqlite.rs | 2 +- src/errors.rs | 4 +- src/models/torrent.rs | 25 ++++++----- src/services/torrent.rs | 47 ++++++++++++--------- src/web/api/v1/contexts/torrent/handlers.rs | 2 +- 7 files changed, 44 insertions(+), 40 deletions(-) diff --git a/src/databases/database.rs b/src/databases/database.rs index 9205d843..462e722b 100644 --- a/src/databases/database.rs +++ b/src/databases/database.rs @@ -196,7 +196,7 @@ pub trait Database: Sync + Send { original_info_hash: &InfoHash, torrent: &Torrent, uploader_id: UserId, - category_id: i64, + category_id: CategoryId, title: &str, description: &str, ) -> Result; diff --git a/src/databases/mysql.rs b/src/databases/mysql.rs index f7dff1ff..9eaef8a7 100644 --- a/src/databases/mysql.rs +++ b/src/databases/mysql.rs @@ -432,7 +432,7 @@ impl Database for Mysql { original_info_hash: &InfoHash, torrent: &Torrent, uploader_id: UserId, - category_id: i64, + category_id: CategoryId, title: &str, description: &str, ) -> Result { diff --git a/src/databases/sqlite.rs b/src/databases/sqlite.rs index ec8d2c01..43d475ca 100644 --- a/src/databases/sqlite.rs +++ b/src/databases/sqlite.rs @@ -422,7 +422,7 @@ impl Database for Sqlite { original_info_hash: &InfoHash, torrent: &Torrent, uploader_id: UserId, - category_id: i64, + category_id: CategoryId, title: &str, description: &str, ) -> Result { diff --git a/src/errors.rs b/src/errors.rs index 29eb12f0..e8ef6712 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -209,9 +209,7 @@ impl From for ServiceError { fn from(e: MetadataError) -> Self { eprintln!("{e}"); match e { - MetadataError::MissingTorrentTitle | MetadataError::MissingTorrentCategoryName => { - ServiceError::MissingMandatoryMetadataFields - } + MetadataError::MissingTorrentTitle => ServiceError::MissingMandatoryMetadataFields, MetadataError::InvalidTorrentTitleLength => ServiceError::InvalidTorrentTitleLength, } } diff --git a/src/models/torrent.rs b/src/models/torrent.rs index b86eb519..1c2d10cc 100644 --- a/src/models/torrent.rs +++ b/src/models/torrent.rs @@ -1,6 +1,7 @@ use derive_more::{Display, Error}; use serde::{Deserialize, Serialize}; +use super::category::CategoryId; use super::torrent_tag::TagId; const MIN_TORRENT_TITLE_LENGTH: usize = 3; @@ -28,12 +29,9 @@ pub struct TorrentListing { #[derive(Debug, Display, PartialEq, Eq, Error)] pub enum MetadataError { - #[display(fmt = "Missing mandatory torrent title")] + #[display(fmt = "Missing mandatory torrent title.")] MissingTorrentTitle, - #[display(fmt = "Missing mandatory torrent category name")] - MissingTorrentCategoryName, - #[display(fmt = "Torrent title is too short.")] InvalidTorrentTitleLength, } @@ -42,7 +40,7 @@ pub enum MetadataError { pub struct Metadata { pub title: String, pub description: String, - pub category: String, + pub category_id: CategoryId, pub tags: Vec, } @@ -53,13 +51,13 @@ impl Metadata { /// /// This function will return an error if the metadata fields do not have a /// valid format. - pub fn new(title: &str, description: &str, category: &str, tag_ids: &[TagId]) -> Result { - Self::validate_format(title, description, category, tag_ids)?; + pub fn new(title: &str, description: &str, category_id: CategoryId, tag_ids: &[TagId]) -> Result { + Self::validate_format(title, description, category_id, tag_ids)?; Ok(Self { title: title.to_owned(), description: description.to_owned(), - category: category.to_owned(), + category_id, tags: tag_ids.to_vec(), }) } @@ -76,15 +74,16 @@ impl Metadata { /// /// This function will return an error if any of the metadata fields does /// not have a valid format. - fn validate_format(title: &str, _description: &str, category: &str, _tag_ids: &[TagId]) -> Result<(), MetadataError> { + fn validate_format( + title: &str, + _description: &str, + _category_id: CategoryId, + _tag_ids: &[TagId], + ) -> Result<(), MetadataError> { if title.is_empty() { return Err(MetadataError::MissingTorrentTitle); } - if category.is_empty() { - return Err(MetadataError::MissingTorrentCategoryName); - } - if title.len() < MIN_TORRENT_TITLE_LENGTH { return Err(MetadataError::InvalidTorrentTitleLength); } diff --git a/src/services/torrent.rs b/src/services/torrent.rs index f6864c06..7ae61848 100644 --- a/src/services/torrent.rs +++ b/src/services/torrent.rs @@ -7,7 +7,7 @@ use serde_derive::{Deserialize, Serialize}; use super::category::DbCategoryRepository; use super::user::DbUserRepository; use crate::config::Configuration; -use crate::databases::database::{Category, Database, Error, Sorting}; +use crate::databases::database::{Database, Error, Sorting}; use crate::errors::ServiceError; use crate::models::category::CategoryId; use crate::models::info_hash::InfoHash; @@ -38,7 +38,7 @@ pub struct Index { pub struct AddTorrentRequest { pub title: String, pub description: String, - pub category: String, + pub category_name: String, pub tags: Vec, pub torrent_buffer: Vec, } @@ -130,23 +130,9 @@ impl Index { user_id: UserId, ) -> Result { // Authorization: only authenticated users ere allowed to upload torrents - let _user = self.user_repository.get_compact(&user_id).await?; - // Validate and build metadata - - let metadata = Metadata::new( - &add_torrent_req.title, - &add_torrent_req.description, - &add_torrent_req.category, - &add_torrent_req.tags, - )?; - - let category = self - .category_repository - .get_by_name(&metadata.category) - .await - .map_err(|_| ServiceError::InvalidCategory)?; + let metadata = self.validate_and_build_metadata(&add_torrent_req).await?; // Validate and build torrent file @@ -198,7 +184,7 @@ impl Index { let torrent_id = self .torrent_repository - .add(&original_info_hash, &torrent, &metadata, user_id, category) + .add(&original_info_hash, &torrent, &metadata, user_id, metadata.category_id) .await?; self.torrent_tag_repository @@ -236,6 +222,27 @@ impl Index { }) } + async fn validate_and_build_metadata(&self, add_torrent_req: &AddTorrentRequest) -> Result { + if add_torrent_req.category_name.is_empty() { + return Err(ServiceError::MissingMandatoryMetadataFields); + } + + let category = self + .category_repository + .get_by_name(&add_torrent_req.category_name) + .await + .map_err(|_| ServiceError::InvalidCategory)?; + + let metadata = Metadata::new( + &add_torrent_req.title, + &add_torrent_req.description, + category.category_id, + &add_torrent_req.tags, + )?; + + Ok(metadata) + } + /// Gets a torrent from the Index. /// /// # Errors @@ -533,14 +540,14 @@ impl DbTorrentRepository { torrent: &Torrent, metadata: &Metadata, user_id: UserId, - category: Category, + category_id: CategoryId, ) -> Result { self.database .insert_torrent_and_get_id( original_info_hash, torrent, user_id, - category.category_id, + category_id, &metadata.title, &metadata.description, ) diff --git a/src/web/api/v1/contexts/torrent/handlers.rs b/src/web/api/v1/contexts/torrent/handlers.rs index 9ddf345d..bab51443 100644 --- a/src/web/api/v1/contexts/torrent/handlers.rs +++ b/src/web/api/v1/contexts/torrent/handlers.rs @@ -396,7 +396,7 @@ async fn build_add_torrent_request_from_payload(mut payload: Multipart) -> Resul Ok(AddTorrentRequest { title, description, - category, + category_name: category, tags, torrent_buffer: torrent_cursor.into_inner(), })