1use compact_str::CompactString;
2use gset::Getset;
3use isocountry::CountryCode;
4use isolanguage_1::LanguageCode;
5use serde::{Deserialize, Deserializer};
6use serde_with::serde_as;
7use time::Date;
8
9time::serde::format_description!(date, Date, "[year]-[month]-[day]");
10
11#[inline]
12fn country_code<'de, D: Deserializer<'de>>(de: D) -> Result<Option<CountryCode>, D::Error> {
13 use serde::de::{Error, Unexpected};
14 match Option::<&str>::deserialize(de)? {
15 None => Ok(None),
16 Some("") => Ok(None),
17 Some(s) if s.len() == 2 => match CountryCode::for_alpha2_caseless(s) {
18 Ok(v) => Ok(Some(v)),
19 Err(_) => Err(D::Error::invalid_value(Unexpected::Str(s), &"any 2-letter ISO 3166-1 country code"))
20 },
21 Some(s) => Err(D::Error::invalid_value(Unexpected::Str(s), &"any 2-letter ISO 3166-1 country code"))
22 }
23}
24
25mod imdb_id {
26 use serde::{Deserialize, Deserializer};
27 use serde::de::{Error, Unexpected};
28
29 #[inline]
30 fn from_str<'de, D: Deserializer<'de>>(s: &str) -> Result<u32, D::Error> {
31 if(s.len() < 3 || &s[..2] != "tt") {
32 return Err(D::Error::invalid_value(Unexpected::Str(s), &"a signed integer prefixed by \"tt\""));
33 }
34 match s[2..].parse() {
35 Ok(v) => Ok(v),
36 Err(_) => Err(D::Error::invalid_value(Unexpected::Str(s), &"a signed integer prefixed by \"tt\""))
37 }
38 }
39
40 #[inline]
41 pub(crate) fn deserialize<'de, D: Deserializer<'de>>(de: D) -> Result<u32, D::Error> {
42 let s = <&str>::deserialize(de)?;
43 from_str::<D>(s)
44 }
45
46 pub(super) mod option {
47 use super::*;
48 #[inline]
49 pub(crate) fn deserialize<'de, D: Deserializer<'de>>(de: D) -> Result<Option<u32>, D::Error> {
50 match Option::<&str>::deserialize(de)? {
51 Some(s) => Ok(Some(from_str::<D>(s)?)),
52 None => Ok(None)
53 }
54 }
55 }
56}
57
58#[derive(Debug, Eq, PartialEq, Deserialize, Getset)]
59pub struct Genre {
60 #[getset(get_copy, vis = "pub")]
61 id: u16,
62 #[getset(get_deref, vis = "pub")]
63 name: CompactString,
64}
65
66#[derive(Debug, Eq, PartialEq, Deserialize, Getset)]
67pub struct Results<T> {
68 #[getset(get_deref, vis = "pub")]
69 results: Vec<T>,
70}
71
72#[derive(Debug, Eq, PartialEq, Deserialize, Getset)]
73pub struct Video {
74 #[getset(get_deref, vis = "pub")]
75 id: CompactString,
76 #[getset(get_copy, vis = "pub")]
77 iso_639_1: LanguageCode,
78 #[getset(get_deref, vis = "pub")]
79 key: CompactString,
80 #[getset(get_deref, vis = "pub")]
81 name: CompactString,
82 #[getset(get_deref, vis = "pub")]
83 site: CompactString,
84 #[getset(get_copy, vis = "pub")]
85 size: u16,
86 #[getset(get_deref, vis = "pub")]
87 #[serde(rename = "type")]
88 video_type: CompactString,
89}
90
91#[serde_as]
92#[derive(Debug, Eq, PartialEq, Deserialize, Getset)]
93pub struct Cast {
94 #[getset(get_copy, vis = "pub")]
95 id: u32,
96 #[getset(get_copy, vis = "pub")]
97 cast_id: u32,
98 #[serde_as(as = "serde_with::hex::Hex")]
99 #[getset(get_copy, vis = "pub")]
100 credit_id: [u8; 12],
101 #[getset(get_deref, vis = "pub")]
102 character: CompactString,
103 #[getset(get_copy, vis = "pub")]
104 gender: Option<u8>,
105 #[getset(get_deref, vis = "pub")]
106 name: CompactString,
107 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
108 profile_path: Option<String>,
109 #[getset(get_copy, vis = "pub")]
110 order: u8,
111}
112
113#[serde_as]
114#[derive(Debug, Eq, PartialEq, Deserialize, Getset)]
115pub struct TVCast {
116 #[getset(get_copy, vis = "pub")]
117 id: u32,
118 #[serde_as(as = "serde_with::hex::Hex")]
119 #[getset(get_copy, vis = "pub")]
120 credit_id: [u8; 12],
121 #[getset(get_deref, vis = "pub")]
122 character: CompactString,
123 #[getset(get_copy, vis = "pub")]
124 gender: Option<u8>,
125 #[getset(get_deref, vis = "pub")]
126 name: CompactString,
127 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
128 profile_path: Option<String>,
129 #[getset(get_copy, vis = "pub")]
130 order: u32,
131}
132
133#[serde_as]
134#[derive(Debug, Eq, PartialEq, Deserialize, Getset)]
135pub struct TVCreator {
136 #[getset(get_copy, vis = "pub")]
137 id: u32,
138 #[serde_as(as = "serde_with::hex::Hex")]
139 #[getset(get_copy, vis = "pub")]
140 credit_id: [u8; 12],
141 #[getset(get_deref, vis = "pub")]
142 name: CompactString,
143 #[getset(get_copy, vis = "pub")]
144 gender: Option<u8>,
145 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
146 profile_path: Option<String>,
147}
148
149#[serde_as]
150#[derive(Debug, Eq, PartialEq, Deserialize, Getset)]
151pub struct Crew {
152 #[serde_as(as = "serde_with::hex::Hex")]
153 #[getset(get_copy, vis = "pub")]
154 credit_id: [u8; 12],
155 #[getset(get_deref, vis = "pub")]
156 department: CompactString,
157 #[getset(get_copy, vis = "pub")]
158 gender: Option<u8>,
159 #[getset(get_copy, vis = "pub")]
160 id: u32,
161 #[getset(get_deref, vis = "pub")]
162 job: CompactString,
163 #[getset(get_deref, vis = "pub")]
164 name: CompactString,
165 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
166 profile_path: Option<String>,
167}
168
169#[derive(Debug, Eq, PartialEq, Deserialize, Getset)]
170pub struct Credits {
171 #[getset(get_deref, vis = "pub")]
172 cast: Vec<Cast>,
173 #[getset(get_deref, vis = "pub")]
174 crew: Vec<Crew>,
175}
176
177#[derive(Debug, Eq, PartialEq, Deserialize, Getset)]
178pub struct TVCredits {
179 #[getset(get_deref, vis = "pub")]
180 cast: Vec<TVCast>,
181 #[getset(get_deref, vis = "pub")]
182 crew: Vec<Crew>,
183}
184
185#[derive(Debug, PartialEq, Deserialize, Getset)]
186pub struct LastEpisode {
187 #[serde(with = "date")]
188 #[getset(get_copy, vis = "pub")]
189 air_date: Date,
190 #[getset(get_copy, vis = "pub")]
191 episode_number: u32,
192 #[getset(get_copy, vis = "pub")]
193 id: u32,
194 #[getset(get_deref, vis = "pub")]
195 name: CompactString,
196 #[getset(get_deref, vis = "pub")]
197 overview: String,
198 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
199 production_code: Option<String>,
200 #[getset(get_copy, vis = "pub")]
201 season_number: u32,
202 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
203 still_path: Option<String>,
204 #[getset(get_copy, vis = "pub")]
205 vote_average: f64,
206 #[getset(get_copy, vis = "pub")]
207 vote_count: u64,
208}
209
210#[derive(Debug, Eq, PartialEq, Deserialize, Getset)]
211pub struct ProductionCompany {
212 #[getset(get_copy, vis = "pub")]
213 id: u32,
214 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
215 logo_path: Option<String>,
216 #[getset(get_deref, vis = "pub")]
217 name: CompactString,
218 #[serde(deserialize_with = "country_code")]
219 #[getset(get_copy, vis = "pub")]
220 origin_country: Option<CountryCode>,
221}
222
223#[derive(Debug, Eq, PartialEq, Deserialize, Getset)]
224pub struct Network {
225 #[getset(get_copy, vis = "pub")]
226 id: u32,
227 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
228 logo_path: Option<String>,
229 #[getset(get_deref, vis = "pub")]
230 name: CompactString,
231 #[serde(deserialize_with = "country_code")]
232 #[getset(get_copy, vis = "pub")]
233 origin_country: Option<CountryCode>,
234}
235
236#[derive(Debug, Eq, PartialEq, Deserialize, Getset)]
237pub struct Season {
238 #[serde(with = "date::option")]
239 #[getset(get_copy, vis = "pub")]
240 air_date: Option<Date>,
241 #[getset(get_copy, vis = "pub")]
242 episode_count: u32,
243 #[getset(get_copy, vis = "pub")]
244 id: u32,
245 #[getset(get_deref, vis = "pub")]
246 name: CompactString,
247 #[getset(get_deref, vis = "pub")]
248 overview: String,
249 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
250 poster_path: Option<String>,
251 #[getset(get_copy, vis = "pub")]
252 season_number: u32,
253}
254
255#[derive(Debug, PartialEq, Deserialize, Getset)]
256pub struct Movie {
257 #[getset(get_copy, vis = "pub")]
258 id: u32,
259 #[serde(with = "imdb_id")]
260 #[getset(get_copy, vis = "pub")]
261 imdb_id: u32,
262 #[getset(get_deref, vis = "pub")]
263 title: CompactString,
264 #[getset(get_deref, vis = "pub")]
265 tagline: String,
266 #[getset(get_deref, vis = "pub")]
267 original_title: CompactString,
268 #[getset(get_copy, vis = "pub")]
269 original_language: LanguageCode,
270 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
271 overview: Option<String>,
272 #[serde(with = "date")]
273 #[getset(get_copy, vis = "pub")]
274 release_date: Date,
275 #[getset(get_copy, vis = "pub")]
276 runtime: u32,
277 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
278 homepage: Option<String>,
279 #[getset(get_deref, vis = "pub")]
280 genres: Vec<Genre>,
281 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
282 poster_path: Option<String>,
283 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
284 backdrop_path: Option<String>,
285 #[getset(get_copy, vis = "pub")]
286 popularity: f64,
287 #[getset(get_copy, vis = "pub")]
288 budget: u64,
289 #[getset(get_copy, vis = "pub")]
290 adult: bool,
291 #[getset(get_as_ref, vis = "pub", ty = "Option<&Results<Video>>")]
292 videos: Option<Results<Video>>,
293 #[getset(get_as_ref, vis = "pub", ty = "Option<&Credits>")]
294 credits: Option<Credits>,
295}
296
297#[derive(Debug, PartialEq, Deserialize, Getset)]
298pub struct TV {
299 #[getset(get_copy, vis = "pub")]
300 id: u32,
301 backdrop_path: Option<String>,
302 #[getset(get_deref, vis = "pub")]
303 created_by: Vec<TVCreator>,
304 #[getset(get_deref, vis = "pub")]
305 episode_run_time: Vec<u16>,
306 #[serde(with = "date")]
307 #[getset(get_copy, vis = "pub")]
308 first_air_date: Date,
309 #[getset(get_deref, vis = "pub")]
310 genres: Vec<Genre>,
311 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
312 homepage: Option<String>,
313 #[getset(get_copy, vis = "pub")]
314 in_production: bool,
315 #[getset(get_deref, vis = "pub")]
316 languages: Vec<LanguageCode>,
317 #[serde(with = "date")]
318 #[getset(get_copy, vis = "pub")]
319 last_air_date: Date,
320 #[getset(get_as_ref, vis = "pub", ty = "Option<&LastEpisode>")]
321 last_episode_to_air: Option<LastEpisode>,
322 #[getset(get_deref, vis = "pub")]
323 name: CompactString,
324 #[getset(get_deref, vis = "pub")]
325 networks: Vec<Network>,
326 #[getset(get_copy, vis = "pub")]
327 number_of_episodes: u32,
328 #[getset(get_copy, vis = "pub")]
329 number_of_seasons: u32,
330 #[getset(get_deref, vis = "pub")]
331 origin_country: Vec<CountryCode>,
332 #[getset(get_copy, vis = "pub")]
333 original_language: LanguageCode,
334 #[getset(get_deref, vis = "pub")]
335 original_name: CompactString,
336 #[getset(get_deref, vis = "pub")]
337 overview: String,
338 #[getset(get_copy, vis = "pub")]
339 popularity: f64,
340 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
341 poster_path: Option<CompactString>,
342 #[getset(get_deref, vis = "pub")]
343 production_companies: Vec<ProductionCompany>,
344 #[getset(get_deref, vis = "pub")]
345 seasons: Vec<Season>,
346 #[getset(get_deref, vis = "pub")]
347 status: CompactString,
348 #[getset(get_deref, vis = "pub")]
349 r#type: CompactString,
350 #[getset(get_copy, vis = "pub")]
351 vote_average: f64,
352 #[getset(get_copy, vis = "pub")]
353 vote_count: u64,
354 #[getset(get_as_ref, vis = "pub", ty = "Option<&Results<Video>>")]
355 videos: Option<Results<Video>>,
356 #[getset(get_as_ref, vis = "pub", ty = "Option<&TVCredits>")]
357 credits: Option<TVCredits>,
358}
359
360#[derive(Debug, PartialEq, Deserialize, Getset)]
361pub struct SearchMovie {
362 #[getset(get_copy, vis = "pub")]
363 id: u32,
364 #[getset(get_deref, vis = "pub")]
365 title: CompactString,
366 #[getset(get_deref, vis = "pub")]
367 original_title: CompactString,
368 #[getset(get_copy, vis = "pub")]
369 original_language: LanguageCode,
370 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
371 overview: Option<String>,
372 #[serde(with = "date")]
373 #[getset(get_copy, vis = "pub")]
374 release_date: Date,
375 #[getset(get_deref, vis = "pub")]
376 genre_ids: Vec<u16>,
377 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
378 poster_path: Option<String>,
379 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
380 backdrop_path: Option<String>,
381 #[getset(get_copy, vis = "pub")]
382 popularity: f64,
383 #[getset(get_copy, vis = "pub")]
384 adult: bool,
385}
386
387#[derive(Debug, PartialEq, Deserialize, Getset)]
388pub struct SearchTV {
389 #[getset(get_copy, vis = "pub")]
390 id: u32,
391 #[getset(get_deref, vis = "pub")]
392 name: CompactString,
393 #[getset(get_deref, vis = "pub")]
394 original_name: CompactString,
395 #[getset(get_copy, vis = "pub")]
396 original_language: LanguageCode,
397 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
398 overview: Option<String>,
399 #[serde(with = "date")]
400 #[getset(get_copy, vis = "pub")]
401 first_air_date: Date,
402 #[getset(get_deref, vis = "pub")]
403 genre_ids: Vec<u16>,
404 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
405 poster_path: Option<String>,
406 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
407 backdrop_path: Option<String>,
408 #[getset(get_copy, vis = "pub")]
409 popularity: f64,
410 #[getset(get_copy, vis = "pub")]
411 vote_average: f32,
412 #[getset(get_copy, vis = "pub")]
413 vote_count: u32,
414}
415
416#[derive(Debug, Eq, PartialEq, Deserialize, Getset)]
417pub struct FindMovie {
418 #[getset(get_copy, vis = "pub")]
419 id: u32,
420 #[getset(get_deref, vis = "pub")]
421 title: CompactString,
422 #[getset(get_deref, vis = "pub")]
423 original_title: CompactString,
424 #[getset(get_copy, vis = "pub")]
425 original_language: LanguageCode,
426 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
427 overview: Option<String>,
428 #[serde(with = "date")]
429 #[getset(get_copy, vis = "pub")]
430 release_date: Date,
431 #[getset(get_deref, vis = "pub")]
432 genre_ids: Vec<u16>,
433 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
434 poster_path: Option<String>,
435 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
436 backdrop_path: Option<String>,
437 #[getset(get_copy, vis = "pub")]
438 adult: bool,
439}
440
441#[derive(Debug, PartialEq, Deserialize, Getset)]
442pub struct FindTV {
443 #[getset(get_copy, vis = "pub")]
444 id: u32,
445 #[getset(get_deref, vis = "pub")]
446 name: CompactString,
447 #[getset(get_deref, vis = "pub")]
448 original_name: CompactString,
449 #[getset(get_copy, vis = "pub")]
450 original_language: LanguageCode,
451 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
452 overview: Option<String>,
453 #[serde(with = "date")]
454 #[getset(get_copy, vis = "pub")]
455 first_air_date: Date,
456 #[getset(get_deref, vis = "pub")]
457 genre_ids: Vec<u16>,
458 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
459 poster_path: Option<String>,
460 #[getset(get_as_deref, vis = "pub", ty = "Option<&str>")]
461 backdrop_path: Option<String>,
462 #[getset(get_copy, vis = "pub")]
463 popularity: f64,
464 #[getset(get_copy, vis = "pub")]
465 vote_average: f32,
466 #[getset(get_copy, vis = "pub")]
467 vote_count: u32,
468}
469
470#[derive(Debug, PartialEq, Deserialize, Getset)]
471pub struct MovieSearchResult {
472 #[getset(get_copy, vis = "pub")]
473 page: u8,
474 #[getset(get_copy, vis = "pub")]
475 total_results: u8,
476 #[getset(get_copy, vis = "pub")]
477 total_pages: u8,
478 #[getset(get_deref, vis = "pub")]
479 results: Vec<SearchMovie>,
480}
481
482#[derive(Debug, PartialEq, Deserialize, Getset)]
483pub struct TVSearchResult {
484 #[getset(get_copy, vis = "pub")]
485 page: u8,
486 #[getset(get_copy, vis = "pub")]
487 total_results: u8,
488 #[getset(get_copy, vis = "pub")]
489 total_pages: u8,
490 #[getset(get_deref, vis = "pub")]
491 results: Vec<SearchTV>,
492}
493
494#[derive(Debug, PartialEq, Deserialize, Getset)]
495pub struct FindResult {
496 #[getset(get_deref, vis = "pub")]
497 movie_results: Vec<FindMovie>,
498 #[getset(get_deref, vis = "pub")]
499 tv_results: Vec<FindTV>
500}
501
502#[derive(Debug, Eq, PartialEq, Deserialize, Getset)]
503pub struct TVExternalIds {
504 #[getset(get_copy, vis = "pub")]
505 id: u32,
506 #[serde(with = "imdb_id::option")]
507 #[getset(get_copy, vis = "pub")]
508 imdb_id: Option<u32>,
509 freebase_mid: Option<CompactString>,
510 freebase_id: Option<CompactString>,
511 #[getset(get_copy, vis = "pub")]
512 tvdb_id: Option<u32>,
513 #[getset(get_copy, vis = "pub")]
514 tvrage_id: Option<u32>,
515 facebook_id: Option<CompactString>,
516 instagram_id: Option<CompactString>,
517 twitter_id: Option<CompactString>
518}
519
520impl TVExternalIds {
521 #[inline]
522 pub fn freebase_mid(&self) -> Option<&str> {
523 self.freebase_mid.as_deref()
524 }
525
526 #[inline]
527 pub fn freebase_id(&self) -> Option<&str> {
528 self.freebase_id.as_deref()
529 }
530
531 #[inline]
532 pub fn facebook_id(&self) -> Option<&str> {
533 self.facebook_id.as_deref()
534 }
535
536 #[inline]
537 pub fn instagram_id(&self) -> Option<&str> {
538 self.instagram_id.as_deref()
539 }
540
541 #[inline]
542 pub fn twitter_id(&self) -> Option<&str> {
543 self.twitter_id.as_deref()
544 }
545}
546