Skip to main content

tmdb_rs/endpoints/
movie.rs

1use serde::Deserialize;
2use time::Date;
3
4use crate::common::{
5    AccountStates, AlternativeTitles, Changes, ExternalIds, Images, StatusResponse, Translations,
6    Videos, WatchProviders,
7};
8use crate::endpoints::credit::Credits;
9use crate::endpoints::genre::Genre;
10use crate::endpoints::keyword::{Keyword, MovieKeywords};
11use crate::endpoints::list::ListShort;
12use crate::endpoints::review::Review;
13use crate::{Backdrop, CountryCode, GuestSessionId, Language, Page, Poster, SessionId};
14
15/// TMDB's release date kinds
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, num_enum::FromPrimitive)]
17#[serde(from = "u32")]
18#[repr(u32)]
19pub enum ReleaseType {
20    Premiere = 1,
21    TheatricalLimited = 2,
22    Theatrical = 3,
23    Digital = 4,
24    Physical = 5,
25    Tv = 6,
26    #[num_enum(default)]
27    Unknown,
28}
29
30#[derive(Debug, Clone, Deserialize)]
31pub struct ReleaseDate {
32    pub certification: String,
33    #[serde(rename = "type")]
34    pub kind: ReleaseType,
35    /// ISO 8601 datetime
36    pub release_date: String,
37    pub note: Option<String>,
38}
39
40#[derive(Debug, Clone, Deserialize)]
41pub struct CountryReleaseDates {
42    #[serde(rename = "iso_3166_1")]
43    pub country: CountryCode,
44    pub release_dates: Vec<ReleaseDate>,
45}
46
47#[derive(Debug, Clone, Deserialize)]
48pub struct ReleaseDates {
49    pub results: Vec<CountryReleaseDates>,
50}
51
52/// one movie in a list or search response
53#[derive(Debug, Clone, Deserialize)]
54pub struct MovieShort {
55    pub id: u64,
56    #[serde(rename = "title")]
57    pub name: String,
58    #[serde(rename = "original_title")]
59    pub original_name: String,
60    pub overview: String,
61    #[serde(default, deserialize_with = "crate::common::opt_date")]
62    pub release_date: Option<Date>,
63    #[serde(rename = "poster_path")]
64    pub poster: Option<Poster>,
65    #[serde(rename = "backdrop_path")]
66    pub backdrop: Option<Backdrop>,
67    pub vote_average: f64,
68    pub vote_count: u32,
69    pub popularity: f64,
70    #[serde(default)]
71    pub genre_ids: Vec<u64>,
72    #[serde(default, deserialize_with = "crate::common::opt_language")]
73    pub original_language: Option<Language>,
74    pub adult: bool,
75    pub video: bool,
76}
77
78endpoint! {
79    /// the primary details of a movie
80    movie(id: u64): GET "/movie/{id}" => MovieDetails {
81        params { language: Language }
82        base {
83            pub id: u64,
84            #[serde(rename = "title")]
85            pub name: String,
86            #[serde(rename = "original_title")]
87            pub original_name: String,
88            pub overview: String,
89            pub tagline: String,
90            #[serde(default, deserialize_with = "crate::common::opt_date")]
91            pub release_date: Option<Date>,
92            pub vote_average: f64,
93            pub vote_count: u32,
94            pub popularity: f64,
95            pub runtime: Option<u32>,
96            #[serde(default, deserialize_with = "crate::common::opt_language")]
97            pub original_language: Option<Language>,
98            #[serde(rename = "poster_path")]
99            pub poster: Option<Poster>,
100            #[serde(rename = "backdrop_path")]
101            pub backdrop: Option<Backdrop>,
102            pub genres: Vec<Genre>,
103            pub imdb_id: Option<String>,
104            #[serde(rename = "homepage")]
105            pub website: String,
106            pub status: String,
107            pub budget: u64,
108            pub revenue: u64,
109            pub adult: bool,
110        }
111        appends {
112            account_states: AccountStates,
113            alternative_titles: AlternativeTitles,
114            changes: Changes,
115            credits: Credits,
116            external_ids: ExternalIds,
117            images: Images,
118            keywords: MovieKeywords,
119            lists: Page<ListShort>,
120            recommendations: Page<MovieShort>,
121            release_dates: ReleaseDates,
122            reviews: Page<Review>,
123            similar: Page<MovieShort>,
124            translations: Translations,
125            videos: Videos,
126            watch_providers: WatchProviders as "watch/providers",
127        }
128    }
129}
130
131endpoint! {
132    /// a movie's account states (favorite, rated, watchlist)
133    movie_account_states(id: u64): GET "/movie/{id}/account_states" => AccountStates {
134        params { session_id: SessionId, guest_session_id: GuestSessionId }
135    }
136}
137
138endpoint! {
139    /// a movie's alternative titles
140    movie_alternative_titles(id: u64): GET "/movie/{id}/alternative_titles" => AlternativeTitles {
141        params { language: Language, country: CountryCode }
142    }
143}
144
145endpoint! {
146    /// a movie's recent changes
147    movie_changes_by_id(id: u64): GET "/movie/{id}/changes" => Changes {
148        params { start_date: Date, end_date: Date, page: u32 }
149    }
150}
151
152endpoint! {
153    /// a movie's credits
154    movie_credits(id: u64): GET "/movie/{id}/credits" => Credits {
155        params { language: Language }
156    }
157}
158
159endpoint! {
160    /// a movie's images
161    movie_images(id: u64): GET "/movie/{id}/images" => Images {
162        params { language: Language, include_image_language: Vec<Language> }
163    }
164}
165
166endpoint! {
167    /// the lists a movie appears in
168    movie_lists(id: u64): GET "/movie/{id}/lists" => Page<ListShort> {
169        params { language: Language, page: u32 }
170    }
171}
172
173endpoint! {
174    /// movies similar to a movie, from TMDB's collaborative filtering
175    movie_similar(id: u64): GET "/movie/{id}/similar" => Page<MovieShort> {
176        params { language: Language, page: u32 }
177    }
178}
179
180endpoint! {
181    /// a movie's recommendations
182    movie_recommendations(id: u64): GET "/movie/{id}/recommendations" => Page<MovieShort> {
183        params { language: Language, page: u32 }
184    }
185}
186
187endpoint! {
188    /// a movie's release dates by country
189    movie_release_dates(id: u64): GET "/movie/{id}/release_dates" => ReleaseDates
190}
191
192endpoint! {
193    /// a movie's reviews
194    movie_reviews(id: u64): GET "/movie/{id}/reviews" => Page<Review> {
195        params { language: Language, page: u32 }
196    }
197}
198
199endpoint! {
200    /// a movie's translations
201    movie_translations(id: u64): GET "/movie/{id}/translations" => Translations
202}
203
204endpoint! {
205    /// a movie's videos (trailers, teasers, ...)
206    movie_videos(id: u64): GET "/movie/{id}/videos" => Videos {
207        params { language: Language, include_image_language: Vec<Language> }
208    }
209}
210
211endpoint! {
212    /// where a movie can be streamed, rented or bought, by country
213    movie_watch_providers(id: u64): GET "/movie/{id}/watch/providers" => WatchProviders
214}
215
216endpoint! {
217    /// rate a movie; pass a session or guest session
218    rate_movie(id: u64): POST "/movie/{id}/rating" => StatusResponse {
219        params { session_id: SessionId, guest_session_id: GuestSessionId }
220        body { value: f64 }
221    }
222}
223
224endpoint! {
225    /// delete a movie rating
226    unrate_movie(id: u64): DELETE "/movie/{id}/rating" => StatusResponse {
227        params { session_id: SessionId, guest_session_id: GuestSessionId }
228    }
229}
230
231endpoint! {
232    /// the current movie ids, paged by insertion order
233    movie_changes(): GET "/movie/changes" => Page<MovieChange> {
234        params { page: u32, start_date: Date, end_date: Date }
235    }
236}
237
238/// a movie touched by a change window
239#[derive(Debug, Clone, Deserialize)]
240pub struct MovieChange {
241    pub id: u64,
242    pub adult: Option<bool>,
243}
244
245endpoint! {
246    /// the newest movie
247    movie_latest(): GET "/movie/latest" => MovieDetails {
248        params { language: Language }
249    }
250}
251
252endpoint! {
253    /// movies currently in theatres
254    movie_now_playing(): GET "/movie/now_playing" => Page<MovieShort> {
255        params { language: Language, page: u32, region: CountryCode }
256    }
257}
258
259endpoint! {
260    /// movies ordered by popularity
261    movie_popular(): GET "/movie/popular" => Page<MovieShort> {
262        params { language: Language, page: u32, region: CountryCode }
263    }
264}
265
266endpoint! {
267    /// movies ordered by rating
268    movie_top_rated(): GET "/movie/top_rated" => Page<MovieShort> {
269        params { language: Language, page: u32, region: CountryCode }
270    }
271}
272
273endpoint! {
274    /// upcoming movies
275    movie_upcoming(): GET "/movie/upcoming" => Page<MovieShort> {
276        params { language: Language, page: u32, region: CountryCode }
277    }
278}
279
280endpoint! {
281    /// a movie's keywords, without the details round-trip
282    movie_keywords(id: u64): GET "/movie/{id}/keywords" => Vec<Keyword> [keywords]
283}
284
285endpoint! {
286    /// a movie's ids on other databases
287    movie_external_ids(id: u64): GET "/movie/{id}/external_ids" => ExternalIds
288}