mal/api/model/
anime.rs

1use crate::config::app_config::{AppConfig, TitleLanguage};
2
3use super::*;
4use serde::{Deserialize, Serialize};
5use std::fmt::Debug;
6use strum_macros::{Display, EnumIter, EnumString, IntoStaticStr};
7
8#[derive(Clone, Debug, Deserialize, Serialize)]
9pub struct AnimeSeason {
10    pub year: u64,
11    pub season: Season,
12}
13
14#[derive(Clone, Debug, PartialEq, EnumString, IntoStaticStr)]
15#[strum(serialize_all = "snake_case")]
16pub enum AnimeField {
17    Id,
18    Titel,
19    MainPicture,
20    AlternativeTitles,
21    StartDate,
22    EndDate,
23    Synopsis,
24    Mean,
25    Rank,
26    Popularity,
27    NumListUsers,
28    NumScoringUsers,
29    NSFW,
30    CreatedAt,
31    UpdatedAt,
32    MediaType,
33    Status,
34    MyListStatus,
35    NumEpisodes,
36    Broadcast,
37    Source,
38    AverageEpisodeDuration,
39    Rating,
40    Pictures,
41    Background,
42    RelatedAnime,
43    RelatedManga,
44    Recommendations,
45    Studios,
46    Statistics,
47
48    NumVolumes,
49    NumChapters,
50    Authors,
51
52    Name,
53    Picture,
54    Gender,
55    Birthday,
56    Location,
57    JoinedAt,
58    AnimeStatistics,
59    TimeZone,
60    IsSupporter,
61}
62
63#[derive(Clone, Debug, PartialEq, EnumString, IntoStaticStr)]
64#[strum(serialize_all = "snake_case")]
65pub enum AnimeMediaType {
66    Unknown,
67    #[strum(serialize = "tv")]
68    TV,
69    #[strum(serialize = "ova")]
70    OVA,
71    Movie,
72    Special,
73    #[strum(serialize = "ona")]
74    ONA,
75    Music,
76    Other(String),
77}
78
79#[derive(Clone, Debug, PartialEq, EnumString, IntoStaticStr)]
80#[strum(serialize_all = "snake_case")]
81pub enum AnimeStatus {
82    FinishedAiring,
83    CurrentlyAiring,
84    NotYetAired,
85    Other(String),
86}
87
88#[derive(Clone, Debug, PartialEq, EnumString, IntoStaticStr, Display)]
89#[strum(serialize_all = "snake_case")]
90pub enum Source {
91    Other,
92    Original,
93    Manga,
94    #[strum(serialize = "4_koma_manga")]
95    YonKomaManga,
96    WebManga,
97    DigitalManga,
98    Novel,
99    LightNovel,
100    VisualNovel,
101    Game,
102    CardGame,
103    Book,
104    PictureBook,
105    Radio,
106    Music,
107}
108
109#[derive(Clone, Debug, Deserialize, Serialize)]
110pub struct UserAnimeListStatus {
111    pub status: UserWatchStatus,
112    pub score: u8,
113    pub num_episodes_watched: u64,
114    pub is_rewatching: bool,
115    pub start_date: Option<DateWrapper>,
116    pub finish_date: Option<DateWrapper>,
117    pub priority: Option<u8>,
118    pub num_times_rewatched: Option<u64>,
119    pub rewatch_value: Option<u8>,
120    pub tags: Option<Vec<String>>,
121    pub comments: Option<String>,
122    pub updated_at: DateTimeWrapper,
123}
124
125#[derive(Clone, Debug, EnumString, IntoStaticStr)]
126pub enum Rating {
127    G,
128    #[strum(serialize = "pg")]
129    PG,
130    #[strum(serialize = "pg_13")]
131    PG13,
132    R,
133    #[strum(serialize = "r+")]
134    Rp,
135    #[strum(serialize = "rx")]
136    RX,
137}
138
139#[derive(Clone, Debug, Deserialize, Serialize)]
140pub struct Anime {
141    pub id: u64,
142    pub title: String,
143    pub main_picture: Option<Picture>,
144    pub alternative_titles: Option<AlternativeTitles>,
145    pub start_date: Option<DateWrapper>,
146    pub end_date: Option<DateWrapper>,
147    pub synopsis: Option<String>,
148    pub mean: Option<f64>,
149    pub rank: Option<u64>,
150    pub popularity: Option<u64>,
151    pub num_list_users: Option<u64>,
152    pub num_scoring_users: Option<u64>,
153    pub nsfw: Option<NSFW>,
154    pub genres: Option<Vec<Genre>>,
155    pub created_at: Option<DateTimeWrapper>,
156    pub updated_at: Option<DateTimeWrapper>,
157    pub media_type: Option<AnimeMediaType>,
158    pub status: Option<AnimeStatus>,
159    pub my_list_status: Option<UserAnimeListStatus>,
160    pub num_episodes: Option<u64>,
161    pub start_season: Option<StartSeason>,
162    pub broadcast: Option<Broadcast>,
163    pub source: Option<Source>,
164    pub average_episode_duration: Option<u64>,
165    pub rating: Option<String>,
166    pub studios: Option<Vec<Studio>>,
167    pub pictures: Option<Vec<Picture>>,
168    pub background: Option<String>,
169    pub related_anime: Option<Vec<RelatedAnime>>,
170    pub related_manga: Option<Vec<RelatedManga>>,
171    pub recommendations: Option<Vec<AnimeRecommendation>>,
172    pub statistics: Option<MediaDetailStatistics>,
173}
174
175#[derive(Clone, Debug, Deserialize, Serialize)]
176pub struct AnimeRecommendation {
177    pub node: Anime,
178    pub num_recommendations: u64,
179}
180#[derive(Clone, Debug, Serialize, Deserialize)]
181pub struct RelatedAnime {
182    pub node: Anime,
183    pub relation_type: RelationType,
184    pub relation_type_formatted: String,
185}
186
187#[derive(Debug, Clone, Deserialize, Serialize)]
188pub struct StartSeason {
189    pub season: Season,
190    pub year: u16,
191}
192
193#[derive(Clone, Debug, PartialEq, EnumString, IntoStaticStr)]
194#[strum(serialize_all = "snake_case")]
195pub enum RelationType {
196    Sequel,
197    Prequel,
198    AlternativeSetting,
199    AlternativeVersion,
200    SideStory,
201    ParentStory,
202    Summary,
203    FullStory,
204    #[strum(serialize = "other")]
205    Other(String),
206}
207
208#[derive(Clone, Debug, PartialEq, EnumString, IntoStaticStr, Display)]
209#[strum(serialize_all = "snake_case")]
210pub enum AnimeRankingType {
211    All,
212    Airing,
213    Upcoming,
214    #[strum(serialize = "tv")]
215    TV,
216    #[strum(serialize = "ova")]
217    OVA,
218    Movie,
219    Special,
220    #[strum(serialize = "popularity")]
221    ByPopularity,
222    Favorite,
223    Other(String),
224}
225
226#[derive(Clone, Debug, Serialize, Deserialize)]
227pub struct RankingAnimePair {
228    pub node: Anime,
229    pub ranking: RankingInfo,
230}
231
232#[derive(Clone, Debug, PartialEq, Display, EnumString, EnumIter, IntoStaticStr)]
233#[strum(serialize_all = "snake_case")]
234pub enum UserWatchStatus {
235    Watching,
236    Completed,
237    OnHold,
238    Dropped,
239    PlanToWatch,
240    #[strum(serialize = "add")]
241    Other(String),
242}
243
244#[derive(Clone, Debug, PartialEq, EnumString, IntoStaticStr)]
245#[strum(serialize_all = "snake_case")]
246pub enum SortStyle {
247    ListScore,
248    ListUpdatedAt,
249    AnimeTitle,
250    AnimeStartDate,
251    AnimeId,
252    Other(String),
253}
254
255impl Anime {
256    pub fn get_title(&self, app_config: &AppConfig, both: bool) -> Vec<String> {
257        if both {
258            vec![
259                self.title.clone(),
260                self.alternative_titles
261                    .as_ref()
262                    .and_then(|alternative_titles| alternative_titles.en.clone())
263                    .unwrap_or_else(|| self.title.clone()),
264            ]
265        } else {
266            match app_config.title_language {
267                TitleLanguage::Japanese => vec![self.title.clone()],
268                TitleLanguage::English => {
269                    if let Some(ref alternative_titles) = self.alternative_titles {
270                        if let Some(ref en) = alternative_titles.en {
271                            if !en.is_empty() {
272                                vec![en.clone()]
273                            } else {
274                                vec![self.title.clone()]
275                            }
276                        } else {
277                            vec![self.title.clone()]
278                        }
279                    } else {
280                        vec![self.title.clone()]
281                    }
282                }
283            }
284        }
285    }
286}