Skip to main content

mal_api/manga/
responses.rs

1use std::fmt::Display;
2
3use crate::common::{
4    AlternativeTitles, Genre, MainPicture, Paging, PagingIter, Ranking, RelationType, NSFW,
5};
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Deserialize, Serialize)]
9pub struct MangaList {
10    pub data: Vec<MangaListNode>,
11    pub paging: Paging,
12}
13
14impl Display for MangaList {
15    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16        write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
17    }
18}
19
20impl PagingIter for MangaList {
21    type Item = Self;
22
23    fn next_page(&self) -> Option<&String> {
24        self.paging.next.as_ref()
25    }
26
27    fn prev_page(&self) -> Option<&String> {
28        self.paging.previous.as_ref()
29    }
30}
31
32#[derive(Debug, Deserialize, Serialize)]
33pub struct MangaListNode {
34    pub node: MangaFields,
35
36    /// This field is only present when querying for a User's anime list
37    pub list_status: Option<MangaListStatus>,
38}
39
40impl Display for MangaListNode {
41    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42        write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
43    }
44}
45
46// Wrap everything in Options since user controls what fields should be returned
47#[derive(Debug, Deserialize, Serialize)]
48pub struct MangaFields {
49    pub id: Option<u32>,
50    pub title: Option<String>,
51    pub main_picture: Option<MainPicture>,
52    pub alternative_titles: Option<AlternativeTitles>,
53    pub start_date: Option<String>,
54    pub end_date: Option<String>,
55    pub synopsis: Option<String>,
56    pub mean: Option<f32>,
57    pub rank: Option<u32>,
58    pub popularity: Option<u32>,
59    pub num_list_users: Option<u32>,
60    pub num_scoring_users: Option<u32>,
61    pub nsfw: Option<NSFW>,
62    pub genres: Option<Vec<Genre>>,
63    pub created_at: Option<String>,
64    pub updated_at: Option<String>,
65    pub media_type: Option<MangaMediaType>,
66    pub status: Option<MangaStatus>,
67    pub my_list_status: Option<MangaListStatus>,
68    pub num_volumes: Option<u32>,
69    pub num_chapters: Option<u32>,
70    pub authors: Option<Vec<Author>>,
71}
72
73impl Display for MangaFields {
74    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75        write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
76    }
77}
78
79#[derive(Debug, Deserialize, Serialize, PartialEq)]
80#[serde(rename_all = "snake_case")]
81pub enum MangaMediaType {
82    Unknown,
83    Manga,
84    Novel,
85    OneShot,
86    Doujinshi,
87    Manhwa,
88    Manhua,
89    Oel,
90    LightNovel,
91}
92
93#[derive(Debug, Deserialize, Serialize, PartialEq)]
94#[serde(rename_all = "snake_case")]
95pub enum MangaStatus {
96    Finished,
97    CurrentlyPublishing,
98    NotYetPublished,
99    OnHiatus, // Undocumented status...
100}
101
102#[derive(Debug, Deserialize, Serialize)]
103pub struct Author {
104    pub node: AuthorDetails,
105    pub role: Option<String>,
106}
107
108impl Display for Author {
109    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
110        write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
111    }
112}
113
114#[derive(Debug, Deserialize, Serialize)]
115pub struct AuthorDetails {
116    pub id: u32,
117    pub first_name: Option<String>,
118    pub last_name: Option<String>,
119}
120
121impl Display for AuthorDetails {
122    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
123        write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
124    }
125}
126
127#[derive(Debug, Deserialize, Serialize)]
128pub struct MangaListStatus {
129    pub status: Option<super::requests::UserMangaListStatus>,
130    pub score: u8,
131    pub num_volumes_read: u32,
132    pub num_chapters_read: u32,
133    pub is_rereading: bool,
134    pub start_date: Option<String>,
135    pub finish_date: Option<String>,
136    pub priority: u8,
137    pub num_times_reread: u32,
138    pub reread_value: u8,
139    pub tags: Vec<String>,
140    pub comments: String,
141    pub updated_at: String,
142}
143
144impl Display for MangaListStatus {
145    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
146        write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
147    }
148}
149
150#[derive(Debug, Deserialize, Serialize)]
151pub struct MangaPicture {
152    pub medium: String,
153    pub large: String,
154}
155
156impl Display for MangaPicture {
157    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
158        write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
159    }
160}
161
162#[derive(Debug, Deserialize, Serialize)]
163pub struct RelatedManga {
164    pub node: MangaFields,
165    pub relation_type: RelationType,
166    pub relation_type_formatted: String,
167}
168
169impl Display for RelatedManga {
170    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
171        write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
172    }
173}
174
175#[derive(Debug, Deserialize, Serialize)]
176pub struct Recommendation {
177    pub node: MangaFields,
178    pub num_recommendations: u32,
179}
180
181impl Display for Recommendation {
182    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
183        write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
184    }
185}
186
187#[derive(Debug, Deserialize, Serialize)]
188pub struct Serialization {
189    pub node: SerializationNode,
190    pub role: Option<String>,
191}
192
193impl Display for Serialization {
194    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
195        write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
196    }
197}
198
199#[derive(Debug, Deserialize, Serialize)]
200pub struct SerializationNode {
201    pub id: u32,
202    pub name: String,
203}
204
205impl Display for SerializationNode {
206    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
207        write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
208    }
209}
210
211#[derive(Debug, Deserialize, Serialize)]
212pub struct MangaDetails {
213    #[serde(flatten)]
214    pub shared_fields: MangaFields,
215
216    pub pictures: Option<Vec<MangaPicture>>,
217    pub background: Option<String>,
218    pub related_anime: Option<Vec<crate::anime::responses::RelatedAnime>>,
219    pub related_manga: Option<Vec<RelatedManga>>,
220    pub recommendations: Option<Vec<Recommendation>>,
221    pub serialization: Option<Vec<Serialization>>,
222}
223
224impl Display for MangaDetails {
225    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
226        write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
227    }
228}
229
230#[derive(Debug, Deserialize, Serialize)]
231pub struct MangaRanking {
232    pub data: Vec<MangaRankingNode>,
233    pub paging: Paging,
234}
235
236impl Display for MangaRanking {
237    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
238        write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
239    }
240}
241
242impl PagingIter for MangaRanking {
243    type Item = Self;
244
245    fn next_page(&self) -> Option<&String> {
246        self.paging.next.as_ref()
247    }
248
249    fn prev_page(&self) -> Option<&String> {
250        self.paging.previous.as_ref()
251    }
252}
253
254#[derive(Debug, Deserialize, Serialize)]
255pub struct MangaRankingNode {
256    pub node: MangaFields,
257    pub ranking: Ranking,
258}
259
260impl Display for MangaRankingNode {
261    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
262        write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
263    }
264}