kodik_api/types.rs
1use serde::{Deserialize, Serialize};
2
3use std::collections::BTreeMap;
4
5/// Represents a release type on Kodik
6#[derive(Serialize, Deserialize, Debug, Clone)]
7pub enum ReleaseType {
8 #[serde(rename = "foreign-movie")]
9 ForeignMovie,
10 #[serde(rename = "soviet-cartoon")]
11 SovietCartoon,
12 #[serde(rename = "foreign-cartoon")]
13 ForeignCartoon,
14 #[serde(rename = "russian-cartoon")]
15 RussianCartoon,
16 #[serde(rename = "anime")]
17 Anime,
18 #[serde(rename = "russian-movie")]
19 RussianMovie,
20 #[serde(rename = "cartoon-serial")]
21 CartoonSerial,
22 #[serde(rename = "documentary-serial")]
23 DocumentarySerial,
24 #[serde(rename = "russian-serial")]
25 RussianSerial,
26 #[serde(rename = "foreign-serial")]
27 ForeignSerial,
28 #[serde(rename = "anime-serial")]
29 AnimeSerial,
30 #[serde(rename = "multi-part-film")]
31 MultiPartFilm,
32}
33
34/// Represents a release quality on Kodik
35#[derive(Serialize, Deserialize, Debug, Clone)]
36pub enum ReleaseQuality {
37 #[serde(rename = "BDRip")]
38 BdRip,
39 #[serde(rename = "BDRip 1080p")]
40 BdRip1080p,
41 #[serde(rename = "BDRip 720p")]
42 BdRip720p,
43 #[serde(rename = "CAMRip")]
44 CamRip,
45 #[serde(rename = "D-VHS")]
46 DVhs,
47 #[serde(rename = "DVBRip")]
48 DvbRip,
49 #[serde(rename = "DVBRip 720p")]
50 DvbRip720p,
51 #[serde(rename = "DVDRip")]
52 DvdRip,
53 #[serde(rename = "DVDSrc")]
54 DvdSrc,
55 #[serde(rename = "HDDVDRip")]
56 HddvdRip,
57 #[serde(rename = "HDDVDRip 1080p")]
58 HddvdRip1080p,
59 #[serde(rename = "HDDVDRip 720p")]
60 HddvdRip720p,
61 #[serde(rename = "HDRip")]
62 HdRip,
63 #[serde(rename = "HDRip 1080p")]
64 HdRip1080p,
65 #[serde(rename = "HDRip 720p")]
66 HdRip720p,
67 #[serde(rename = "HDTVRip")]
68 HdtvRip,
69 #[serde(rename = "HDTVRip 1080p")]
70 HdtvRip1080p,
71 #[serde(rename = "HDTVRip 720p")]
72 HdtvRip720p,
73 #[serde(rename = "IPTVRip")]
74 IptvRip,
75 #[serde(rename = "Laserdisc-RIP")]
76 LaserdiscRip,
77 #[serde(rename = "SATRip")]
78 SatRip,
79 #[serde(rename = "SuperTS")]
80 SuperTs,
81 #[serde(rename = "TS")]
82 Ts,
83 #[serde(rename = "TS 720p")]
84 Ts720p,
85 #[serde(rename = "TVRip")]
86 TvRip,
87 #[serde(rename = "TVRip 720p")]
88 TvRip720p,
89 #[serde(rename = "VHSRip")]
90 VhsRip,
91 #[serde(rename = "WEB-DLRip")]
92 WebDlRip,
93 #[serde(rename = "WEB-DLRip 1080p")]
94 WebDlRip1080p,
95 #[serde(rename = "WEB-DLRip 720p")]
96 WebDlRip720p,
97 #[serde(rename = "Workprint-AVC")]
98 WorkprintAvc,
99 #[serde(other)]
100 Unknown,
101}
102
103/// Represents a release on Kodik
104#[derive(Serialize, Deserialize, Debug, Clone)]
105pub struct Release {
106 /// `"movie-452654"`
107 pub id: String,
108
109 /// `"Аватар"`
110 pub title: String,
111
112 /// `"Avatar"`
113 pub title_orig: String,
114
115 /// Other titles that are often used in anime
116 pub other_title: Option<String>,
117
118 /// `"http://kodik.cc/video/19850/6476310cc6d90aa9304d5d8af3a91279/720p"`
119 pub link: String,
120
121 /// Year of release of the title
122 pub year: i32,
123
124 /// `43949`
125 pub kinopoisk_id: Option<String>,
126
127 /// `tt0084716`
128 pub imdb_id: Option<String>,
129
130 /// `1245`
131 pub mdl_id: Option<String>,
132
133 /// Link to the material on World Art (not using ID because there are different
134 pub worldart_link: Option<String>,
135
136 /// `1234`
137 pub shikimori_id: Option<String>,
138
139 #[serde(rename = "type")]
140 pub release_type: ReleaseType,
141
142 pub quality: ReleaseQuality,
143
144 /// Is the material a camrip
145 pub camrip: bool,
146
147 /// Does the material contain LGBT scenes
148 pub lgbt: bool,
149
150 /// The team that did the translation
151 pub translation: Translation,
152
153 /// ISO 8601
154 pub created_at: String,
155
156 /// ISO 8601
157 pub updated_at: String,
158
159 /// If the series is blocked entirely, this field contains the string `"all"`. If individual seasons are blocked, the field is an object containing season numbers, and for each season: either `"all"` (if all episodes are blocked) or an array of episode numbers `["1", "2", "3"]` (if individual episodes are blocked). If nothing is blocked, the field is an empty object. This field is present only in materials with the series type.
160 pub blocked_seasons: Option<BTreeMap<String, BlockedSeason>>,
161
162 /// Object with seasons and episodes in them. This field is present only if the parameters `with_seasons` or `with_episodes`, `with_episodes_data` were specified in the request.
163 pub seasons: Option<BTreeMap<String, Season>>,
164
165 /// Number of the last season of the series. This field is present only in materials with the series type.
166 pub last_season: Option<i32>,
167
168 /// Number of the last episode of the series. This field is present only in materials with the series type.
169 pub last_episode: Option<i32>,
170
171 /// Total number of episodes in the series. This field is present only in materials with the series type.
172 pub episodes_count: Option<i32>,
173
174 /// Array containing countries where the material is blocked. Empty array if the material is not blocked anywhere.
175 pub blocked_countries: Vec<String>,
176
177 pub material_data: Option<MaterialData>,
178
179 /// Links to frames from the video. For series, frames from the first episode are displayed in the main information. To get frames from each episode, use the `with_episodes_data`.
180 pub screenshots: Vec<String>,
181}
182
183/// Represents a release blocked season on Kodik
184#[derive(Serialize, Deserialize, Debug, Clone)]
185pub enum BlockedSeason {
186 All,
187
188 Episodes(Vec<String>),
189}
190
191/// Represents a release season object on Kodik
192#[derive(Serialize, Deserialize, Debug, Clone)]
193pub struct Season {
194 /// For example, it can be marked as a recap, special, etc.
195 pub title: Option<String>,
196
197 pub link: String,
198
199 pub episodes: BTreeMap<String, EpisodeUnion>,
200}
201
202/// Represents a release episode on Kodik
203#[derive(Serialize, Deserialize, Debug, Clone)]
204#[serde(untagged)]
205pub enum EpisodeUnion {
206 /// `"http://kodik.cc/seria/119611/09249413a7eb3c03b15df57cd56a051b/720p"`
207 Link(String),
208
209 Episode(Episode),
210}
211
212/// Represents a release episode object on Kodik
213#[derive(Serialize, Deserialize, Debug, Clone)]
214pub struct Episode {
215 /// For example, it сan be marked as special
216 pub title: Option<String>,
217
218 /// `"http://kodik.cc/seria/119611/09249413a7eb3c03b15df57cd56a051b/720p"`
219 pub link: String,
220
221 pub screenshots: Vec<String>,
222}
223
224/// Represents a release translation type on Kodik
225#[derive(Serialize, Deserialize, Debug, Clone)]
226pub enum TranslationType {
227 #[serde(rename = "subtitles")]
228 Subtitles,
229
230 #[serde(rename = "voice")]
231 Voice,
232}
233
234/// Represents a release translation on Kodik
235#[derive(Serialize, Deserialize, Debug, Clone)]
236pub struct Translation {
237 pub id: i32,
238
239 /// Name of the translation team
240 pub title: String,
241
242 /// Specifies what the translation team does
243 #[serde(rename = "type")]
244 pub translation_type: TranslationType,
245}
246
247/// Represents a release anime kind on Kodik
248#[derive(Serialize, Deserialize, Debug, Clone)]
249pub enum AnimeKind {
250 #[serde(rename = "tv")]
251 Tv,
252 #[serde(rename = "movie")]
253 Movie,
254 #[serde(rename = "ova")]
255 Ova,
256 #[serde(rename = "ona")]
257 Ona,
258 #[serde(rename = "special")]
259 Special,
260 #[serde(rename = "music")]
261 Music,
262 #[serde(rename = "tv_13")]
263 Tv13,
264 #[serde(rename = "tv_24")]
265 Tv24,
266 #[serde(rename = "tv_48")]
267 Tv48,
268}
269
270/// Represents a release all kind on Kodik
271#[derive(Serialize, Deserialize, Debug, Clone)]
272pub enum AllStatus {
273 #[serde(rename = "anons")]
274 Anons,
275 #[serde(rename = "ongoing")]
276 Ongoing,
277 #[serde(rename = "released")]
278 Released,
279}
280
281/// Represents a release anime status on Kodik
282#[derive(Serialize, Deserialize, Debug, Clone)]
283pub enum AnimeStatus {
284 #[serde(rename = "anons")]
285 Anons,
286 #[serde(rename = "ongoing")]
287 Ongoing,
288 #[serde(rename = "released")]
289 Released,
290}
291
292/// Represents a release drama status on Kodik
293#[derive(Serialize, Deserialize, Debug, Clone)]
294pub enum DramaStatus {
295 #[serde(rename = "anons")]
296 Anons,
297 #[serde(rename = "ongoing")]
298 Ongoing,
299 #[serde(rename = "released")]
300 Released,
301}
302
303/// Represents a release MPPA rating on Kodik
304#[derive(Serialize, Deserialize, Debug, Clone)]
305pub enum MppaRating {
306 /// `0+ `
307 #[serde(rename = "G")]
308 G,
309 /// `6+`
310 #[serde(rename = "PG")]
311 Pg,
312 /// `12+`
313 #[serde(rename = "PG-13")]
314 Pg13,
315 /// `16+`
316 #[serde(rename = "R")]
317 R,
318 /// `18+ `
319 #[serde(rename = "R+")]
320 RPlus,
321 /// `21+`
322 #[serde(rename = "Rx")]
323 Rx,
324}
325
326/// Represents a release material data field
327#[derive(Serialize, Deserialize, Debug, Clone)]
328pub enum MaterialDataField {
329 #[serde(rename = "kinopoisk_id")]
330 /// kinopoisk_id
331 KinopoiskId,
332 #[serde(rename = "imdb_id")]
333 /// imdb_id
334 ImdbId,
335 #[serde(rename = "mdl_id")]
336 /// mdl_id
337 MdlId,
338 #[serde(rename = "worldart_link")]
339 /// worldart_link
340 WorldartLink,
341 #[serde(rename = "shikimori_id")]
342 /// shikimori_id
343 ShikimoriId,
344}
345
346/// Represents various data related to a material, such as title, description, ratings, etc.
347#[derive(Serialize, Deserialize, Debug, Clone)]
348pub struct MaterialData {
349 /// `"Аватар"`
350 ///
351 /// Source: `KinoPoisk`, `Shikimori`
352 pub title: Option<String>,
353
354 /// `"Аватар"`
355 ///
356 /// Source: `Shikimori`
357 pub anime_title: Option<String>,
358
359 /// Original title
360 ///
361 /// `"Avatar"`
362 ///
363 /// Source: `KinoPoisk`, `Shikimori`, `MyDramaList`
364 pub title_en: Option<String>,
365
366 /// `["Аватар", "Аватар 2", "Аватар 3"]`
367 ///
368 /// Source: `Shikimori`, `MyDramaList`
369 pub other_titles: Option<Vec<String>>,
370
371 /// `["Avatar", "Avatar 2", "Avatar 3"]`
372 ///
373 /// Source: `Shikimori`
374 pub other_titles_en: Option<Vec<String>>,
375
376 /// `["アバター", "アバター 2", "アバター 3"]`
377 ///
378 /// Source: `Shikimori`
379 pub other_titles_jp: Option<Vec<String>>,
380
381 /// `"Avatar"`
382 ///
383 /// Source: `Shikimori`
384 pub anime_license_name: Option<String>,
385
386 /// License holders
387 ///
388 /// `["Wakanim", "Русский Репортаж"]`
389 ///
390 /// Source: `Shikimori`
391 pub anime_licensed_by: Option<Vec<String>>,
392
393 /// Source: `Shikimori`
394 pub anime_kind: Option<AnimeKind>,
395
396 /// Material status from all sources
397 ///
398 /// Source: `Shikimori`, `MyDramaList`
399 pub all_status: Option<AllStatus>,
400
401 /// Source: `Shikimori`
402 pub anime_status: Option<AnimeStatus>,
403
404 /// Source: `MyDramaList`
405 pub drama_status: Option<DramaStatus>,
406
407 /// Year of release of the title
408 ///
409 /// `2016`
410 ///
411 /// Source: `KinoPoisk`
412 pub year: Option<i32>,
413
414 /// `"«An entire universe. Once and for all»"`
415 ///
416 /// Source: `KinoPoisk`
417 pub tagline: Option<String>,
418
419 /// `"Пока Мстители и их союзники продо..."`
420 ///
421 /// Source: `KinoPoisk`, `Shikimori`
422 pub description: Option<String>,
423
424 /// `"Пока Мстители и их союзники продо..."`
425 ///
426 /// Source: `Shikimori`
427 pub anime_description: Option<String>,
428
429 /// `"https://st.kp.yandex.net/images/film_iphone/iphone360_840471.jpg"`
430 ///
431 /// Source: `KinoPoisk`, `Shikimori`, `MyDramaList`
432 pub poster_url: Option<String>,
433
434 /// `["https://site.com/image1.png", "https://site.com/image2.png"]`
435 ///
436 /// Source: `Shikimori`
437 pub screenshots: Option<Vec<String>>,
438
439 /// Duration in minutes
440 ///
441 /// `160`
442 ///
443 /// Source: `KinoPoisk`, `Shikimori`, `MyDramaList`
444 pub duration: Option<i32>,
445
446 /// `["США", "Великобритания"]`
447 ///
448 /// Source: `KinoPoisk`, `MyDramaList`
449 pub countries: Option<Vec<String>>,
450
451 /// Genres from all available sources
452 ///
453 /// `["комедия", "боевик"]`
454 ///
455 /// Source: `KinoPoisk`, `Shikimori`, `MyDramaList`
456 pub all_genres: Option<Vec<String>>,
457
458 /// `["комедия", "боевик"]`
459 ///
460 /// Source: `KinoPoisk`
461 pub genres: Option<Vec<String>>,
462
463 /// `["приключения","комедия"]`
464 ///
465 /// Source: `Shikimori`
466 pub anime_genres: Option<Vec<String>>,
467
468 /// `["приключения","комедия"]`
469 ///
470 /// Source: `MyDramaList`
471 pub drama_genres: Option<Vec<String>>,
472
473 /// `["Studio Deen"]`
474 ///
475 /// Source: `Shikimori`
476 pub anime_studios: Option<Vec<String>>,
477
478 /// `7.2`
479 ///
480 /// Source: `KinoPoisk`
481 pub kinopoisk_rating: Option<f64>,
482
483 /// Number of votes on Kinopoisk
484 ///
485 /// `723856`
486 ///
487 /// Source: `KinoPoisk`
488 pub kinopoisk_votes: Option<i32>,
489
490 /// `7.2`
491 ///
492 /// Source: `KinoPoisk`
493 pub imdb_rating: Option<f64>,
494
495 /// Number of votes on IMDb
496 ///
497 /// `723856`
498 ///
499 /// Source: `KinoPoisk`
500 pub imdb_votes: Option<i32>,
501
502 /// `7.2`
503 ///
504 /// Source: `Shikimori`
505 pub shikimori_rating: Option<f32>,
506
507 /// Number of votes on Shikimori
508 ///
509 /// Source: `Shikimori`
510 pub shikimori_votes: Option<i32>,
511
512 /// `7.2`
513 ///
514 /// Source: `MyDramaList`
515 pub mydramalist_rating: Option<f32>,
516
517 /// Number of votes on MyDramaList
518 ///
519 /// Source: `MyDramaList`
520 pub mydramalist_votes: Option<i32>,
521
522 /// Premiere date in Russia
523 ///
524 /// `"2018-04-16"`
525 ///
526 /// Source: `KinoPoisk`
527 pub premiere_ru: Option<String>,
528
529 /// Worldwide premiere date
530 ///
531 /// `"2018-04-16"`
532 ///
533 /// Source: `KinoPoisk`
534 pub premiere_world: Option<String>,
535
536 /// Airing start date
537 ///
538 /// `"2018-04-16"`
539 ///
540 /// Source: `Shikimori`, `MyDramaList`
541 pub aired_at: Option<String>,
542
543 /// Airing end date
544 ///
545 /// `"2018-04-16"`
546 ///
547 /// Source: `Shikimori`, `MyDramaList`
548 pub released_at: Option<String>,
549
550 /// Next episode release time
551 ///
552 /// `"2021-04-06T14:19:27Z"`
553 ///
554 /// Source: `Shikimori`, `MyDramaList`
555 pub next_episode_at: Option<String>,
556
557 /// MPAA rating
558 /// Source: `KinoPoisk`, `Shikimori`
559 pub rating_mpaa: Option<MppaRating>,
560
561 /// Minimum age to watch
562 ///
563 /// `16`
564 ///
565 /// Source: `KinoPoisk`, `MyDramaList`
566 pub minimal_age: Option<i32>,
567
568 /// Total number of episodes
569 ///
570 /// `14`
571 ///
572 /// Source: `Shikimori`, `MyDramaList`
573 pub episodes_total: Option<i32>,
574
575 /// Number of aired episodes
576 ///
577 /// `14`
578 ///
579 /// Source: `Shikimori`, `MyDramaList`
580 pub episodes_aired: Option<i32>,
581
582 /// `["Роберт Дауни мл.", "Крис Хемсворт", "Марк Руффало"]`
583 ///
584 /// Source: `KinoPoisk`, `MyDramaList`
585 pub actors: Option<Vec<String>>,
586
587 /// `["Роберт Дауни мл.", "Крис Хемсворт", "Марк Руффало"]`
588 ///
589 /// Source: `KinoPoisk`, `MyDramaList`
590 pub directors: Option<Vec<String>>,
591
592 /// `["Роберт Дауни мл.", "Крис Хемсворт", "Марк Руффало"]`
593 ///
594 /// Source: `KinoPoisk`, `MyDramaList`
595 pub producers: Option<Vec<String>>,
596
597 /// `["Роберт Дауни мл.", "Крис Хемсворт", "Марк Руффало"]`
598 ///
599 /// Source: `KinoPoisk`, `MyDramaList`
600 pub writers: Option<Vec<String>>,
601
602 /// `["Роберт Дауни мл.", "Крис Хемсворт", "Марк Руффало"]`
603 ///
604 /// Source: `KinoPoisk`, `MyDramaList`
605 pub composers: Option<Vec<String>>,
606
607 /// `["Роберт Дауни мл.", "Крис Хемсворт", "Марк Руффало"]`
608 ///
609 /// Source: `KinoPoisk`, `MyDramaList`
610 pub editors: Option<Vec<String>>,
611
612 /// `["Роберт Дауни мл.", "Крис Хемсворт", "Марк Руффало"]`
613 ///
614 /// Source: `KinoPoisk`, `MyDramaList`
615 pub designers: Option<Vec<String>>,
616
617 /// `["Роберт Дауни мл.", "Крис Хемсворт", "Марк Руффало"]`
618 ///
619 /// Source: `KinoPoisk`, `MyDramaList`
620 pub operators: Option<Vec<String>>,
621}