use async_trait::async_trait;
use super::{
media_id::MediaId,
models::{
UnifiedEpisode, UnifiedMovie, UnifiedMovieDetails, UnifiedPerson, UnifiedPersonDetails,
UnifiedSearchResult, UnifiedSeasonDetails, UnifiedTvShow, UnifiedTvShowDetails,
UnifiedWatchProviders,
},
};
use crate::core::{error::ProviderError, pagination::Page};
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Capability {
Search,
Details,
Discovery,
Recommendations,
Seasons,
WatchAvailability,
}
pub trait Provider: Send + Sync {
fn id(&self) -> &str;
fn capabilities(&self) -> &[Capability];
fn supports(&self, capability: Capability) -> bool {
self.capabilities().contains(&capability)
}
}
#[async_trait]
pub trait SearchProvider: Provider {
async fn search_movies(
&self,
query: &str,
page: Option<u32>,
) -> Result<Page<UnifiedMovie>, ProviderError>;
async fn search_tv_shows(
&self,
query: &str,
page: Option<u32>,
) -> Result<Page<UnifiedTvShow>, ProviderError>;
async fn search_people(
&self,
query: &str,
page: Option<u32>,
) -> Result<Page<UnifiedPerson>, ProviderError>;
async fn search_multi(
&self,
query: &str,
page: Option<u32>,
) -> Result<Page<UnifiedSearchResult>, ProviderError>;
}
#[async_trait]
pub trait DetailProvider: Provider {
async fn movie_details(&self, id: &MediaId) -> Result<UnifiedMovieDetails, ProviderError>;
async fn tv_show_details(&self, id: &MediaId) -> Result<UnifiedTvShowDetails, ProviderError>;
async fn person_details(&self, id: &MediaId) -> Result<UnifiedPersonDetails, ProviderError>;
}
#[async_trait]
pub trait DiscoveryProvider: Provider {
async fn trending_movies(
&self,
time_window: crate::core::config::TimeWindow,
page: Option<u32>,
) -> Result<Page<UnifiedMovie>, ProviderError>;
async fn trending_tv_shows(
&self,
time_window: crate::core::config::TimeWindow,
page: Option<u32>,
) -> Result<Page<UnifiedTvShow>, ProviderError>;
async fn popular_movies(&self, page: Option<u32>) -> Result<Page<UnifiedMovie>, ProviderError>;
async fn top_rated_movies(
&self,
page: Option<u32>,
) -> Result<Page<UnifiedMovie>, ProviderError>;
async fn popular_tv_shows(
&self,
page: Option<u32>,
) -> Result<Page<UnifiedTvShow>, ProviderError>;
async fn top_rated_tv_shows(
&self,
page: Option<u32>,
) -> Result<Page<UnifiedTvShow>, ProviderError>;
}
#[async_trait]
pub trait RecommendationProvider: Provider {
async fn movie_recommendations(
&self,
id: &MediaId,
page: Option<u32>,
) -> Result<Page<UnifiedMovie>, ProviderError>;
async fn tv_recommendations(
&self,
id: &MediaId,
page: Option<u32>,
) -> Result<Page<UnifiedTvShow>, ProviderError>;
async fn similar_movies(
&self,
id: &MediaId,
page: Option<u32>,
) -> Result<Page<UnifiedMovie>, ProviderError>;
async fn similar_tv_shows(
&self,
id: &MediaId,
page: Option<u32>,
) -> Result<Page<UnifiedTvShow>, ProviderError>;
}
#[async_trait]
pub trait SeasonProvider: Provider {
async fn season_details(
&self,
show_id: &MediaId,
season_number: u32,
) -> Result<UnifiedSeasonDetails, ProviderError>;
async fn episode_details(
&self,
show_id: &MediaId,
season_number: u32,
episode_number: u32,
) -> Result<UnifiedEpisode, ProviderError>;
}
#[async_trait]
pub trait WatchAvailabilityProvider: Provider {
async fn movie_watch_providers(
&self,
id: &MediaId,
) -> Result<UnifiedWatchProviders, ProviderError>;
async fn tv_watch_providers(
&self,
id: &MediaId,
) -> Result<UnifiedWatchProviders, ProviderError>;
}
pub trait MediaProvider: SearchProvider + DetailProvider + DiscoveryProvider {}
impl<T> MediaProvider for T where T: SearchProvider + DetailProvider + DiscoveryProvider {}