use reqwest::{ header::{HeaderMap, HeaderName, HeaderValue}, Client, ClientBuilder, }; use serde::{Deserialize, Serialize}; pub struct Trakt { client: Client, } impl Trakt { pub fn new(api_key: &str) -> Self { let client = ClientBuilder::new() .default_headers(HeaderMap::from_iter([ ( HeaderName::from_static("trakt-api-key"), HeaderValue::from_str(api_key).unwrap(), ), ( HeaderName::from_static("trakt-api-version"), HeaderValue::from_static("2"), ), ( HeaderName::from_static("content-type"), HeaderValue::from_static("application/json"), ), ])) .build() .unwrap(); Self { client } } pub async fn search( &self, types: &[TraktKind], query: &str, extended: bool, ) -> anyhow::Result> { let res = self .client .get(format!( "https://api.trakt.tv/search/{}?query={}{}", types .iter() .map(|t| serde_json::to_string(t).unwrap()) .collect::>() .join(","), urlencoding::encode(query), optext(extended) )) .send() .await?; Ok(res.json().await?) } } fn optext(extended: bool) -> &'static str { if extended { "&extended=full" } else { "" } } #[derive(Debug, Serialize, Deserialize, Clone, Copy)] #[serde(rename_all = "snake_case")] pub enum TraktKind { Movie, Show, Season, Episode, Person, User, } impl TraktKind { pub fn singular(self) -> &'static str { match self { TraktKind::Movie => "movie", TraktKind::Show => "show", TraktKind::Season => "season", TraktKind::Episode => "episode", TraktKind::Person => "person", TraktKind::User => "user", } } pub fn plural(self) -> &'static str { match self { TraktKind::Movie => "movies", TraktKind::Show => "shows", TraktKind::Season => "seasons", TraktKind::Episode => "episodes", TraktKind::Person => "people", TraktKind::User => "user", // //! not used in API } } } #[derive(Debug, Serialize, Deserialize)] pub struct TraktSearchResult { r#type: TraktKind, score: f64, inner: TraktKindObject, } #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum TraktKindObject { Movie(TraktMediaObject), Show(TraktMediaObject), Season(TraktMediaObject), Episode(TraktMediaObject), Person(TraktMediaObject), User(TraktMediaObject), } #[derive(Debug, Serialize, Deserialize)] pub struct TraktMediaObject { title: String, year: Option, ids: TraktMediaObjectIds, } #[derive(Debug, Serialize, Deserialize)] pub struct TraktMediaObjectIds { trakt: u64, slug: String, imdb: Option, tmdb: Option, }