use crate::common::{MediaType, StatusResponse};
use crate::endpoints::list::ListShort;
use crate::endpoints::movie::MovieShort;
use crate::endpoints::search::MultiResult;
use crate::endpoints::tv::TvShort;
use crate::{AccessToken, Backdrop, Client, CountryCode, Language, Page, Poster, Result};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use strum::Display;
#[derive(Clone)]
pub struct V4(Client);
impl V4 {
pub(crate) fn new(client: Client) -> Self {
Self(client)
}
pub(crate) async fn get<T: DeserializeOwned>(
&self,
path: &str,
query: &[(&str, String)],
) -> Result<T> {
self.0.get(path, query).await
}
pub(crate) async fn post<T: DeserializeOwned>(
&self,
path: &str,
query: &[(&str, String)],
body: &serde_json::Value,
) -> Result<T> {
self.0.post(path, query, body).await
}
pub(crate) async fn put<T: DeserializeOwned>(
&self,
path: &str,
query: &[(&str, String)],
body: &serde_json::Value,
) -> Result<T> {
self.0.put(path, query, body).await
}
pub(crate) async fn delete<T: DeserializeOwned>(
&self,
path: &str,
query: &[(&str, String)],
body: &serde_json::Value,
) -> Result<T> {
self.0.delete(path, query, body).await
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Display)]
pub enum V4Sort {
#[strum(serialize = "original_order.asc")]
OriginalOrderAsc,
#[strum(serialize = "original_order.desc")]
OriginalOrderDesc,
#[strum(serialize = "title.asc")]
TitleAsc,
#[strum(serialize = "title.desc")]
TitleDesc,
#[strum(serialize = "release_date.asc")]
ReleaseDateAsc,
#[strum(serialize = "release_date.desc")]
ReleaseDateDesc,
#[strum(serialize = "vote_average.asc")]
VoteAverageAsc,
#[strum(serialize = "vote_average.desc")]
VoteAverageDesc,
#[strum(serialize = "created_at.asc")]
CreatedAtAsc,
#[strum(serialize = "created_at.desc")]
CreatedAtDesc,
}
impl crate::ToParam for V4Sort {
fn to_param(&self) -> String {
self.to_string()
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct V4RequestToken {
pub success: bool,
pub status_code: i32,
pub status_message: String,
pub request_token: String,
}
impl V4RequestToken {
pub fn redirect_url(&self) -> String {
format!(
"https://www.themoviedb.org/auth/access?request_token={}",
self.request_token
)
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct V4AccessToken {
pub success: bool,
pub status_code: i32,
pub status_message: String,
pub account_id: String,
pub access_token: String,
}
impl V4AccessToken {
pub fn token(&self) -> AccessToken {
AccessToken::new(self.access_token.clone())
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct V4List {
pub id: u64,
pub name: String,
pub description: String,
pub public: bool,
#[serde(rename = "iso_639_1")]
pub language: Option<Language>,
#[serde(rename = "iso_3166_1")]
pub country: Option<CountryCode>,
pub item_count: u32,
pub average_rating: Option<f64>,
#[serde(rename = "backdrop_path")]
pub backdrop: Option<Backdrop>,
#[serde(rename = "poster_path")]
pub poster: Option<Poster>,
pub created_by: Option<String>,
pub sort_by: Option<String>,
pub page: u32,
pub total_pages: u32,
pub total_results: u64,
#[serde(default)]
pub results: Vec<MultiResult>,
}
#[derive(Debug, Clone, Copy, Serialize)]
pub struct ListItem {
pub media_type: MediaType,
pub media_id: u64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ItemResult {
pub media_id: u64,
pub media_type: String,
pub success: bool,
#[serde(default)]
pub error: Vec<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ItemsResponse {
pub success: bool,
pub status_code: i32,
pub status_message: String,
#[serde(default)]
pub results: Vec<ItemResult>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct V4CreateListResponse {
pub success: bool,
pub status_code: i32,
pub status_message: String,
pub id: Option<u64>,
}
endpoint! {
@gen V4,
v4_request_token(): POST "/auth/request_token" => V4RequestToken {
body { redirect_to: &str }
}
}
endpoint! {
@gen V4,
v4_access_token(): POST "/auth/access_token" => V4AccessToken {
body { request_token: &str }
}
}
endpoint! {
@gen V4,
v4_delete_access_token(): DELETE "/auth/access_token" => StatusResponse {
body { access_token: &str }
}
}
endpoint! {
@gen V4,
v4_list(id: u64): GET "/list/{id}" => V4List {
params { language: Language, page: u32, sort_by: V4Sort }
}
}
endpoint! {
@gen V4,
v4_create_list(): POST "/list" => V4CreateListResponse {
body { name: &str, iso_639_1: &str, description: &str, public: bool }
}
}
endpoint! {
@gen V4,
v4_update_list(id: u64): PUT "/list/{id}" => StatusResponse {
body { name: &str, description: &str, public: bool }
}
}
endpoint! {
@gen V4,
v4_delete_list(id: u64): DELETE "/list/{id}" => StatusResponse {
body {}
}
}
endpoint! {
@gen V4,
v4_list_add_items(id: u64): POST "/list/{id}/items" => ItemsResponse {
body { items: Vec<ListItem> }
}
}
endpoint! {
@gen V4,
v4_list_remove_items(id: u64): DELETE "/list/{id}/items" => ItemsResponse {
body { items: Vec<ListItem> }
}
}
endpoint! {
@gen V4,
v4_list_clear(id: u64): GET "/list/{id}/clear" => StatusResponse
}
endpoint! {
@gen V4,
v4_account_lists(account_id: &str): GET "/account/{account_id}/lists" => Page<ListShort> {
params { page: u32 }
}
}
endpoint! {
@gen V4,
v4_favorite_movies(account_id: &str): GET "/account/{account_id}/movie/favorites" => Page<MovieShort> {
params { language: Language, page: u32, sort_by: V4Sort }
}
}
endpoint! {
@gen V4,
v4_favorite_tv(account_id: &str): GET "/account/{account_id}/tv/favorites" => Page<TvShort> {
params { language: Language, page: u32, sort_by: V4Sort }
}
}
endpoint! {
@gen V4,
v4_movie_recommendations(account_id: &str): GET "/account/{account_id}/movie/recommendations" => Page<MovieShort> {
params { language: Language, page: u32, sort_by: V4Sort }
}
}
endpoint! {
@gen V4,
v4_tv_recommendations(account_id: &str): GET "/account/{account_id}/tv/recommendations" => Page<TvShort> {
params { language: Language, page: u32, sort_by: V4Sort }
}
}
endpoint! {
@gen V4,
v4_watchlist_movies(account_id: &str): GET "/account/{account_id}/movie/watchlist" => Page<MovieShort> {
params { language: Language, page: u32, sort_by: V4Sort }
}
}
endpoint! {
@gen V4,
v4_watchlist_tv(account_id: &str): GET "/account/{account_id}/tv/watchlist" => Page<TvShort> {
params { language: Language, page: u32, sort_by: V4Sort }
}
}
endpoint! {
@gen V4,
v4_rated_movies(account_id: &str): GET "/account/{account_id}/movie/rated" => Page<MovieShort> {
params { language: Language, page: u32, sort_by: V4Sort }
}
}
endpoint! {
@gen V4,
v4_rated_tv(account_id: &str): GET "/account/{account_id}/tv/rated" => Page<TvShort> {
params { language: Language, page: u32, sort_by: V4Sort }
}
}
endpoint! {
@gen V4,
v4_mark_favorite(account_id: &str): POST "/account/{account_id}/favorites" => StatusResponse {
body { media_type: MediaType, media_id: u64, favorite: bool }
}
}
endpoint! {
@gen V4,
v4_set_watchlist(account_id: &str): POST "/account/{account_id}/watchlist" => StatusResponse {
body { media_type: MediaType, media_id: u64, watchlist: bool }
}
}