1use reqwest::Client;
8use serde::{Deserialize, Serialize};
9
10use std::{cmp::Ordering, fmt::Debug, ops::Not};
11
12use crate::ImageBoards;
13
14use self::{extension::Extension, rating::Rating, tags::Tag};
15
16pub mod error;
17pub mod extension;
18pub mod rating;
19pub mod tags;
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
23pub enum NameType {
24 ID,
25 MD5,
26}
27
28impl Not for NameType {
29 type Output = Self;
30
31 fn not(self) -> Self::Output {
32 match self {
33 Self::ID => Self::MD5,
34 Self::MD5 => Self::ID,
35 }
36 }
37}
38
39#[derive(Debug)]
41pub struct PostQueue {
42 pub imageboard: ImageBoards,
44 pub client: Client,
46 pub posts: Vec<Post>,
48 pub tags: Vec<String>,
50}
51
52impl PostQueue {
53 pub fn prepare(&mut self, limit: Option<u16>) {
54 if let Some(max) = limit {
55 self.posts.truncate(max as usize);
56 } else {
57 self.posts.shrink_to_fit()
58 }
59 }
60}
61
62#[derive(Clone, Serialize, Deserialize, Eq)]
64pub struct Post {
65 pub id: u64,
67 pub website: ImageBoards,
69 pub url: String,
71 pub md5: String,
73 pub extension: Extension,
77 pub rating: Rating,
84 pub tags: Vec<Tag>,
88}
89
90impl Debug for Post {
91 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92 f.debug_struct("Post")
93 .field("Post ID", &self.id)
94 .field("Website", &self.website)
95 .field("Download URL", &self.url)
96 .field("MD5 Hash", &self.md5)
97 .field("File Extension", &self.extension)
98 .field("Rating", &self.rating)
99 .field("Tag List", &self.tags)
100 .finish()
101 }
102}
103
104impl Ord for Post {
105 fn cmp(&self, other: &Self) -> Ordering {
106 self.id.cmp(&other.id)
107 }
108}
109
110impl PartialOrd for Post {
111 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
112 Some(self.cmp(other))
113 }
114}
115
116impl PartialEq for Post {
117 fn eq(&self, other: &Self) -> bool {
118 self.id == other.id
119 }
120}
121
122impl Post {
123 #[inline]
125 pub fn file_name(&self, name_type: NameType) -> String {
126 let name = match name_type {
127 NameType::ID => self.id.to_string(),
128 NameType::MD5 => self.md5.to_string(),
129 };
130
131 format!("{}.{}", name, self.extension)
132 }
133
134 #[inline]
136 pub fn name(&self, name_type: NameType) -> String {
137 match name_type {
138 NameType::ID => self.id.to_string(),
139 NameType::MD5 => self.md5.to_string(),
140 }
141 }
142
143 #[inline]
144 pub fn seq_file_name(&self, num_digits: usize) -> String {
145 format!("{:0num_digits$}.{}", self.id, self.extension)
146 }
147}