1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use serde::de::Unexpected;
use serde::Deserialize;
use serde::Deserializer;
use serde::Serialize;
use serde_repr::Deserialize_repr;
use serde_repr::Serialize_repr;
use smartstring::alias::String;
#[derive(Debug, Deserialize, Serialize)]
pub struct Title {
pub imdb_id: u64,
pub title_type: TitleType,
pub primary_title: String,
pub original_title: String,
pub is_adult: bool,
pub start_year: Option<u16>,
pub end_year: Option<u16>,
pub runtime_minutes: Option<u16>,
pub genres: Vec<String>
}
impl From<TitleFromImdb> for Title {
fn from(input: TitleFromImdb) -> Self {
Self{
imdb_id: input.imdb_id,
title_type: input.title_type.into(),
primary_title: input.primary_title,
original_title: input.original_title,
is_adult: input.is_adult != 0,
start_year: input.start_year,
end_year: input.end_year,
runtime_minutes: input.runtime_minutes,
genres: input.genres
}
}
}
#[derive(Clone, Copy, Debug, Deserialize_repr, Eq, PartialEq, Serialize_repr, strum::IntoStaticStr)]
#[repr(u8)]
pub enum TitleType {
Short = 0,
Movie = 1,
Episode = 2,
TVSeries = 3,
TVShort = 4,
TVSpecial = 5,
Video = 6,
VideoGame = 7,
Audiobook = 8,
RadioSeries = 9,
RadioEpisode = 10
}
impl From<TitleTypeFromImdb> for TitleType {
fn from(input: TitleTypeFromImdb) -> Self {
match input {
TitleTypeFromImdb::Short => Self::Short,
TitleTypeFromImdb::Movie => Self::Movie,
TitleTypeFromImdb::Episode => Self::Episode,
TitleTypeFromImdb::TVSeries => Self::TVSeries,
TitleTypeFromImdb::TVShort => Self::TVShort,
TitleTypeFromImdb::TVSpecial => Self::TVSpecial,
TitleTypeFromImdb::Video => Self::Video,
TitleTypeFromImdb::VideoGame => Self::VideoGame,
TitleTypeFromImdb::Audiobook => Self::Audiobook,
TitleTypeFromImdb::RadioSeries => Self::RadioSeries,
TitleTypeFromImdb::RadioEpisode => Self::RadioEpisode
}
}
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct TitleFromImdb {
#[serde(rename = "tconst", deserialize_with = "crate::util::parse_imdb_id")]
pub imdb_id: u64,
pub title_type: TitleTypeFromImdb,
pub primary_title: String,
pub original_title: String,
pub is_adult: u8,
#[serde(deserialize_with = "crate::util::parse_janky_tsv_option")]
pub start_year: Option<u16>,
#[serde(deserialize_with = "crate::util::parse_janky_tsv_option")]
pub end_year: Option<u16>,
#[serde(deserialize_with = "crate::util::parse_janky_tsv_option")]
pub runtime_minutes: Option<u16>,
#[serde(with = "serde_with::StringWithSeparator::<serde_with::CommaSeparator>")]
pub genres: Vec<String>
}
#[derive(Debug, Eq, PartialEq)]
pub(crate) enum TitleTypeFromImdb {
Short,
Movie,
Episode,
TVSeries,
TVShort,
TVSpecial,
Video,
VideoGame,
Audiobook,
RadioSeries,
RadioEpisode
}
impl<'de> Deserialize<'de> for TitleTypeFromImdb {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let s: &str = Deserialize::deserialize(deserializer)?;
Ok(match s {
"short" => Self::Short,
"episode" | "tvEpisode" | "tvPilot" => Self::Episode,
"movie" | "tvMovie" => Self::Movie,
"tvSeries" | "tvMiniSeries" => Self::TVSeries,
"tvShort" => Self::TVShort,
"tvSpecial" => Self::TVSpecial,
"video" => Self::Video,
"videoGame" => Self::VideoGame,
"audiobook" => Self::Audiobook,
"radioSeries" => Self::RadioSeries,
"radioEpisode" => Self::RadioEpisode,
s => return Err(serde::de::Error::invalid_value(Unexpected::Str(s), &"'short', 'episode', 'tvEpisode', 'tvPilot', 'movie', 'tvMovie', 'tvSeries', 'tvMiniSeries', 'tvShort', 'tvSpecial', 'video', 'videoGame', 'audiobook', 'radioSeries', 'radioEpisode'"))
})
}
}