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}