torrust_index/models/
torrent.rs

1use derive_more::{Display, Error};
2use serde::{Deserialize, Serialize};
3
4use super::category::CategoryId;
5use super::torrent_tag::TagId;
6
7const MIN_TORRENT_TITLE_LENGTH: usize = 3;
8
9#[allow(clippy::module_name_repetitions)]
10pub type TorrentId = i64;
11
12#[allow(clippy::module_name_repetitions)]
13#[allow(dead_code)]
14#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
15pub struct TorrentListing {
16    pub torrent_id: TorrentId,
17    pub uploader: String,
18    pub info_hash: String,
19    pub title: String,
20    pub description: Option<String>,
21    pub category_id: Option<i64>,
22    pub date_uploaded: String,
23    pub file_size: i64,
24    pub seeders: i64,
25    pub leechers: i64,
26    pub name: String,
27    pub comment: Option<String>,
28    pub creation_date: Option<i64>,
29    pub created_by: Option<String>,
30    pub encoding: Option<String>,
31}
32
33#[derive(Debug, Display, PartialEq, Eq, Error)]
34pub enum MetadataError {
35    #[display(fmt = "Missing mandatory torrent title.")]
36    MissingTorrentTitle,
37
38    #[display(fmt = "Torrent title is too short.")]
39    InvalidTorrentTitleLength,
40}
41
42#[derive(Debug, Deserialize)]
43pub struct Metadata {
44    pub title: String,
45    pub description: String,
46    pub category_id: CategoryId,
47    pub tags: Vec<TagId>,
48}
49
50impl Metadata {
51    /// Create a new struct.
52    ///
53    /// # Errors
54    ///
55    /// This function will return an error if the metadata fields do not have a
56    /// valid format.
57    pub fn new(title: &str, description: &str, category_id: CategoryId, tag_ids: &[TagId]) -> Result<Self, MetadataError> {
58        Self::validate_format(title, description, category_id, tag_ids)?;
59
60        Ok(Self {
61            title: title.to_owned(),
62            description: description.to_owned(),
63            category_id,
64            tags: tag_ids.to_vec(),
65        })
66    }
67
68    /// It validates the format of the metadata fields.
69    ///
70    /// It does not validate domain rules, like:
71    ///
72    /// - Duplicate titles.
73    /// - Non-existing categories.
74    /// - ...
75    ///
76    /// # Errors
77    ///
78    /// This function will return an error if any of the metadata fields does
79    /// not have a valid format.
80    fn validate_format(
81        title: &str,
82        _description: &str,
83        _category_id: CategoryId,
84        _tag_ids: &[TagId],
85    ) -> Result<(), MetadataError> {
86        if title.is_empty() {
87            return Err(MetadataError::MissingTorrentTitle);
88        }
89
90        if title.len() < MIN_TORRENT_TITLE_LENGTH {
91            return Err(MetadataError::InvalidTorrentTitleLength);
92        }
93
94        Ok(())
95    }
96}