1use std::fmt::Display;
2
3use crate::common::{
4 AlternativeTitles, Genre, MainPicture, Paging, PagingIter, Ranking, RelationType, NSFW,
5};
6use serde::{Deserialize, Serialize};
7use serde_json::{self, Value};
8
9#[derive(Debug, Deserialize, Serialize)]
10pub struct AnimeList {
11 pub data: Vec<AnimeListNode>,
12 pub paging: Paging,
13}
14
15impl PagingIter for AnimeList {
16 type Item = Self;
17
18 fn next_page(&self) -> Option<&String> {
19 self.paging.next.as_ref()
20 }
21
22 fn prev_page(&self) -> Option<&String> {
23 self.paging.previous.as_ref()
24 }
25}
26
27impl Display for AnimeList {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
30 }
31}
32
33#[derive(Debug, Deserialize, Serialize)]
34pub struct AnimeListNode {
35 pub node: AnimeFields,
36
37 pub list_status: Option<AnimeListStatus>,
39}
40
41impl Display for AnimeListNode {
42 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43 write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
44 }
45}
46
47#[derive(Debug, Deserialize, Serialize)]
48pub struct AnimePicture {
49 pub medium: String,
50 pub large: String,
51}
52
53impl Display for AnimePicture {
54 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55 write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
56 }
57}
58
59#[derive(Debug, Deserialize, Serialize, PartialEq)]
60#[serde(rename_all = "snake_case")]
61pub enum AnimeMediaType {
62 Unknown,
63 TvSpecial, Tv,
65 Cm, Ova,
67 Movie,
68 Special,
69 Ona,
70 Music,
71 Pv, }
73
74#[derive(Debug, Deserialize, Serialize, PartialEq)]
75#[serde(rename_all = "snake_case")]
76pub enum AnimeStatus {
77 FinishedAiring,
78 CurrentlyAiring,
79 NotYetAired,
80}
81
82#[derive(Debug, Deserialize, Serialize)]
83pub struct AnimeListStatus {
84 pub status: Option<super::requests::UserAnimeListStatus>,
85 pub score: u8,
86 pub num_episodes_watched: u32,
87 pub is_rewatching: bool,
88 pub start_date: Option<String>,
89 pub finish_date: Option<String>,
90 pub priority: u8,
91 pub num_times_rewatched: u32,
92 pub rewatch_value: u8,
93 pub tags: Vec<String>,
94 pub comments: String,
95 pub updated_at: String,
96}
97
98impl Display for AnimeListStatus {
99 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100 write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
101 }
102}
103
104#[derive(Debug, Deserialize, Serialize)]
105pub struct StartSeason {
106 pub year: u32,
107 pub season: super::requests::Season,
108}
109
110impl Display for StartSeason {
111 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
112 write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
113 }
114}
115
116#[derive(Debug, Deserialize, Serialize)]
117pub struct Broadcast {
118 pub day_of_the_week: String,
119 pub start_time: Option<String>,
120}
121
122impl Display for Broadcast {
123 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
124 write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
125 }
126}
127
128#[derive(Debug, Deserialize, Serialize, PartialEq)]
129#[serde(rename_all = "snake_case")]
130pub enum Source {
131 Other,
132 Original,
133 Manga,
134 #[serde(rename = "4_koma_manga")]
135 KomaManga,
136 WebManga,
137 DigitalMedia,
138 Novel,
139 LightNovel,
140 VisualNovel,
141 Game,
142 CardGame,
143 Book,
144 PictureBook,
145 MixedMedia, Radio,
147 Music,
148 WebNovel, }
150
151#[derive(Debug, Deserialize, Serialize, PartialEq)]
152#[serde(rename_all = "lowercase")]
153pub enum Rating {
154 G,
155 PG,
156 #[serde(rename = "pg_13")]
157 PG13,
158 R,
159 #[serde(rename = "r+")]
160 RP,
161 RX,
162}
163
164#[derive(Debug, Deserialize, Serialize)]
165pub struct Studio {
166 pub id: u32,
167 pub name: String,
168}
169
170impl Display for Studio {
171 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
172 write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
173 }
174}
175
176#[derive(Debug, Deserialize, Serialize)]
178pub struct AnimeFields {
179 pub id: u32,
180 pub title: String,
181 pub main_picture: Option<MainPicture>,
182 pub alternative_titles: Option<AlternativeTitles>,
183 pub start_date: Option<String>,
184 pub end_date: Option<String>,
185 pub synopsis: Option<String>,
186 pub mean: Option<f32>,
187 pub rank: Option<u32>,
188 pub popularity: Option<u32>,
189 pub num_list_users: Option<u32>,
190 pub num_scoring_users: Option<u32>,
191 pub nsfw: Option<NSFW>,
192 pub genres: Option<Vec<Genre>>,
193 pub created_at: Option<String>,
194 pub updated_at: Option<String>,
195 pub media_type: Option<AnimeMediaType>,
196 pub status: Option<AnimeStatus>,
197 pub my_list_status: Option<AnimeListStatus>,
198 pub num_episodes: Option<u32>,
199 pub start_season: Option<StartSeason>,
200 pub broadcast: Option<Broadcast>,
201 pub source: Option<Source>,
202 pub average_episode_duration: Option<u32>,
203 pub rating: Option<Rating>,
204 pub studios: Option<Vec<Studio>>,
205}
206
207impl Display for AnimeFields {
208 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
209 write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
210 }
211}
212
213#[derive(Debug, Deserialize, Serialize)]
214pub struct RelatedAnime {
215 pub node: AnimeFields,
216 pub relation_type: RelationType,
217 pub relation_type_formatted: String,
218}
219
220impl Display for RelatedAnime {
221 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
222 write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
223 }
224}
225
226#[derive(Debug, Deserialize, Serialize)]
227pub struct Recommendations {
228 pub node: AnimeFields,
229 pub num_recommendations: u32,
230}
231
232impl Display for Recommendations {
233 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
234 write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
235 }
236}
237
238#[derive(Debug, Deserialize, Serialize)]
239pub struct Statistics {
240 pub num_list_users: u32,
241 pub status: StatisticsStatus,
242}
243
244impl Display for Statistics {
245 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
246 write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
247 }
248}
249
250#[derive(Debug, Deserialize, Serialize)]
251pub struct StatisticsStatus {
252 #[serde(deserialize_with = "deserialize_string_to_u32")]
255 pub watching: u32,
256 #[serde(deserialize_with = "deserialize_string_to_u32")]
257 pub completed: u32,
258 #[serde(deserialize_with = "deserialize_string_to_u32")]
259 pub on_hold: u32,
260 #[serde(deserialize_with = "deserialize_string_to_u32")]
261 pub dropped: u32,
262 #[serde(deserialize_with = "deserialize_string_to_u32")]
263 pub plan_to_watch: u32,
264}
265
266impl Display for StatisticsStatus {
267 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
268 write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
269 }
270}
271
272fn deserialize_string_to_u32<'de, D>(deserializer: D) -> Result<u32, D::Error>
273where
274 D: serde::Deserializer<'de>,
275{
276 let value: Value = Deserialize::deserialize(deserializer)?;
277 if let Some(number) = value.as_str().and_then(|s| s.parse().ok()) {
278 Ok(number)
279 } else {
280 Err(serde::de::Error::custom("Invalid value for u32"))
281 }
282}
283
284#[derive(Debug, Deserialize, Serialize)]
285pub struct AnimeDetails {
286 #[serde(flatten)]
287 pub shared_fields: AnimeFields,
288
289 pub pictures: Option<Vec<AnimePicture>>,
290 pub background: Option<String>,
291 pub related_anime: Option<Vec<RelatedAnime>>,
292 pub related_manga: Option<Vec<crate::manga::responses::RelatedManga>>,
293 pub recommendations: Option<Vec<Recommendations>>,
294 pub statistics: Option<Statistics>,
295}
296
297impl Display for AnimeDetails {
298 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
299 write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
300 }
301}
302
303#[derive(Debug, Deserialize, Serialize)]
304pub struct AnimeRanking {
305 pub data: Vec<AnimeRankingNode>,
306 pub paging: Paging,
307}
308
309impl Display for AnimeRanking {
310 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
311 write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
312 }
313}
314
315impl PagingIter for AnimeRanking {
316 type Item = Self;
317
318 fn next_page(&self) -> Option<&String> {
319 self.paging.next.as_ref()
320 }
321
322 fn prev_page(&self) -> Option<&String> {
323 self.paging.previous.as_ref()
324 }
325}
326
327#[derive(Debug, Deserialize, Serialize)]
328pub struct AnimeRankingNode {
329 pub node: AnimeFields,
330 pub ranking: Ranking,
331}
332
333impl Display for AnimeRankingNode {
334 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
335 write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
336 }
337}
338
339#[derive(Debug, Deserialize, Serialize)]
340pub struct SeasonalAnime {
341 pub data: Vec<SeasonalAnimeNode>,
342 pub paging: Paging,
343}
344
345impl Display for SeasonalAnime {
346 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
347 write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
348 }
349}
350
351impl PagingIter for SeasonalAnime {
352 type Item = Self;
353
354 fn next_page(&self) -> Option<&String> {
355 self.paging.next.as_ref()
356 }
357
358 fn prev_page(&self) -> Option<&String> {
359 self.paging.previous.as_ref()
360 }
361}
362
363#[derive(Debug, Deserialize, Serialize)]
364pub struct SeasonalAnimeNode {
365 pub node: AnimeFields,
366}
367
368impl Display for SeasonalAnimeNode {
369 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
370 write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
371 }
372}
373
374#[derive(Debug, Deserialize, Serialize)]
375pub struct SuggestedAnime {
376 pub data: Vec<SuggestedAnimeNode>,
377 pub paging: Paging,
378}
379
380impl Display for SuggestedAnime {
381 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
382 write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
383 }
384}
385
386impl PagingIter for SuggestedAnime {
387 type Item = Self;
388
389 fn next_page(&self) -> Option<&String> {
390 self.paging.next.as_ref()
391 }
392
393 fn prev_page(&self) -> Option<&String> {
394 self.paging.previous.as_ref()
395 }
396}
397
398#[derive(Debug, Deserialize, Serialize)]
399pub struct SuggestedAnimeNode {
400 pub node: AnimeFields,
401}
402
403impl Display for SuggestedAnimeNode {
404 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
405 write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
406 }
407}