Skip to content

Commit

Permalink
refactor: [#276] extract function Torrent::validate_and_build_metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
josecelano committed Sep 20, 2023
1 parent ca6e97c commit a46d300
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 40 deletions.
2 changes: 1 addition & 1 deletion src/databases/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<i64, Error>;
Expand Down
2 changes: 1 addition & 1 deletion src/databases/mysql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<i64, database::Error> {
Expand Down
2 changes: 1 addition & 1 deletion src/databases/sqlite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<i64, database::Error> {
Expand Down
4 changes: 1 addition & 3 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,7 @@ impl From<MetadataError> 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,
}
}
Expand Down
25 changes: 12 additions & 13 deletions src/models/torrent.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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,
}
Expand All @@ -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<TagId>,
}

Expand All @@ -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, MetadataError> {
Self::validate_format(title, description, category, tag_ids)?;
pub fn new(title: &str, description: &str, category_id: CategoryId, tag_ids: &[TagId]) -> Result<Self, MetadataError> {
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(),
})
}
Expand All @@ -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);
}
Expand Down
47 changes: 27 additions & 20 deletions src/services/torrent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<TagId>,
pub torrent_buffer: Vec<u8>,
}
Expand Down Expand Up @@ -130,23 +130,9 @@ impl Index {
user_id: UserId,
) -> Result<AddTorrentResponse, ServiceError> {
// 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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -236,6 +222,27 @@ impl Index {
})
}

async fn validate_and_build_metadata(&self, add_torrent_req: &AddTorrentRequest) -> Result<Metadata, ServiceError> {
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
Expand Down Expand Up @@ -533,14 +540,14 @@ impl DbTorrentRepository {
torrent: &Torrent,
metadata: &Metadata,
user_id: UserId,
category: Category,
category_id: CategoryId,
) -> Result<TorrentId, Error> {
self.database
.insert_torrent_and_get_id(
original_info_hash,
torrent,
user_id,
category.category_id,
category_id,
&metadata.title,
&metadata.description,
)
Expand Down
2 changes: 1 addition & 1 deletion src/web/api/v1/contexts/torrent/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
})
Expand Down

0 comments on commit a46d300

Please sign in to comment.