1use serde::{Deserialize, Serialize};
6use tosho_macros::AutoGetter;
7
8use super::Image;
9
10#[derive(Debug, Clone, AutoGetter, Serialize, Deserialize)]
12pub struct Creator {
13 name: String,
15 uuid: String,
17}
18
19#[derive(Debug, Clone, AutoGetter, Serialize, Deserialize)]
21pub struct Publisher {
22 name: String,
24 uuid: String,
26 slug: String,
28}
29
30#[derive(Debug, Clone, AutoGetter, Serialize, Deserialize)]
32pub struct Label {
33 #[serde(rename = "label")]
35 name: String,
36 uuid: String,
38}
39
40#[derive(Debug, Clone, AutoGetter, Serialize, Deserialize)]
42pub struct SortOptions {
43 r#type: String,
45 name: String,
47}
48
49#[derive(Debug, Clone, AutoGetter, Serialize, Deserialize)]
51pub struct Tag {
52 name: String,
54 slug: String,
56}
57
58#[derive(Debug, Clone, AutoGetter, Serialize, Deserialize)]
60pub struct HomeGenre {
61 name: String,
63 tag: String,
65}
66
67#[derive(Debug, Clone, AutoGetter, Serialize, Deserialize)]
69pub struct MangaFilters {
70 sort_options: Vec<SortOptions>,
72 tags: Vec<Tag>,
74 bool_options: Vec<String>,
76 publishers: Vec<Publisher>,
78}
79
80#[derive(Debug, Clone, AutoGetter, Serialize, Deserialize)]
82pub struct Product {
83 uuid: String,
85 #[serde(rename = "item_type")]
87 r#type: String,
88 retail_price: String,
90 sale_price: String,
92}
93
94#[derive(Debug, Clone, AutoGetter, Serialize, Deserialize, PartialEq)]
96pub struct ChapterRange {
97 start: String,
99 end: String,
101}
102
103#[derive(Debug, Clone, AutoGetter, Serialize, Deserialize, PartialEq)]
105pub struct ChapterGap {
106 range: ChapterRange,
108}
109
110#[derive(Debug, Clone, Copy, AutoGetter, Serialize, Deserialize, PartialEq)]
112pub struct ChapterExplainer {
113 #[serde(rename = "num_chapters")]
115 count: i32,
116}
117
118#[derive(Debug, Clone, Copy, AutoGetter, Serialize, Deserialize, PartialEq)]
120pub struct SeparatorChapterExplainer {
121 #[serde(rename = "list_index")]
123 index: i32,
124 data: ChapterExplainer,
126}
127
128#[derive(Debug, Clone, AutoGetter, Serialize, Deserialize, PartialEq)]
130pub struct SeparatorChapterGap {
131 #[serde(rename = "list_index")]
133 index: i32,
134 data: ChapterGap,
136}
137
138#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
140#[serde(tag = "type")]
141pub enum Separator {
142 #[serde(rename = "SEPARATOR_PREMIUM_NOTICE")]
144 PremiumNotice(SeparatorChapterExplainer),
145 #[serde(rename = "SEPARATOR_ALC_NOTICE")]
147 AlaCarteNotice(SeparatorChapterExplainer),
148 #[serde(rename = "SEPARATOR_CHAPTER_GAP")]
150 ChapterGap(SeparatorChapterGap),
151 #[serde(rename = "SEPARATOR_UNKNOWN")]
153 Unknown,
154}
155
156#[derive(Debug, Clone, AutoGetter, Serialize, Deserialize)]
158pub struct Volume {
159 uuid: String,
161 #[serde(rename = "manga_uuid")]
163 manga: String,
164 isbn: Option<String>,
166 #[serde(rename = "image")]
168 cover: Image,
169 #[serde(rename = "full_name")]
171 title: String,
172 #[serde(rename = "short_name")]
174 short_title: String,
175 #[serde(rename = "label")]
177 volume: String,
178 #[serde(rename = "is_drm_free")]
180 drm_free: bool,
181 #[serde(rename = "product", default)]
183 retail: Option<Product>,
184 #[serde(rename = "order_number")]
186 order: i32,
187}
188
189#[cfg(test)]
190mod tests {
191 use super::*;
192
193 #[test]
194 fn test_separator_premium_notice() {
195 let json_test = r#"{
196 "type": "SEPARATOR_PREMIUM_NOTICE",
197 "list_index": 0,
198 "data": {
199 "num_chapters": 1
200 }
201 }"#;
202
203 let separator: Separator = serde_json::from_str(json_test).unwrap();
204 match separator {
205 Separator::PremiumNotice(data) => {
206 assert_eq!(data.index, 0);
207 assert_eq!(data.data.count, 1);
208 }
209 _ => panic!("Invalid separator type"),
210 }
211 }
212
213 #[test]
214 fn test_separator_alacarte_notice() {
215 let json_test = r#"{
216 "type": "SEPARATOR_ALC_NOTICE",
217 "list_index": 0,
218 "data": {
219 "num_chapters": 1
220 }
221 }"#;
222
223 let separator: Separator = serde_json::from_str(json_test).unwrap();
224 match separator {
225 Separator::AlaCarteNotice(data) => {
226 assert_eq!(data.index, 0);
227 assert_eq!(data.data.count, 1);
228 }
229 _ => panic!("Invalid separator type"),
230 }
231 }
232
233 #[test]
234 fn test_separator_chapter_gap() {
235 let json_test = r#"{
236 "type": "SEPARATOR_CHAPTER_GAP",
237 "list_index": 0,
238 "data": {
239 "range": {
240 "start": "1",
241 "end": "2"
242 }
243 }
244 }"#;
245
246 let separator: Separator = serde_json::from_str(json_test).unwrap();
247 match separator {
248 Separator::ChapterGap(data) => {
249 assert_eq!(data.index, 0);
250 assert_eq!(data.data.range.start, "1");
251 assert_eq!(data.data.range.end, "2");
252 }
253 _ => panic!("Invalid separator type"),
254 }
255 }
256
257 #[test]
258 fn test_separator_unknown() {
259 let json_test = r#"{
260 "type": "SEPARATOR_UNKNOWN"
261 }"#;
262
263 let separator: Separator = serde_json::from_str(json_test).unwrap();
264 assert_eq!(separator, Separator::Unknown)
265 }
266}