use std::collections::HashSet;
use chrono::{DateTime, Utc};
use crate::entity::language::Language;
use crate::entity::media_file::{MediaFileDocument, MediaFileEntity};
use crate::entity::prelude::{AsStr, Page, Sort};
use crate::entity::tvshow::{TvShowDocument, TvShowEntity, TvShowSource};
use crate::entity::tvshow_season::{TvShowSeasonDocument, TvShowSeasonEntity};
use crate::entity::{Couple, Entity, Relation};
crate::create_kind!(TvShowEpisodeKind, "tvshow-episodes");
pub type TvShowEpisodeEntity = Entity<u64, TvShowEpisodeKind>;
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TvShowEpisodeDocument {
pub id: u64,
#[serde(rename = "type")]
pub kind: TvShowEpisodeKind,
pub attributes: TvShowEpisodeAttributes,
pub relationships: TvShowEpisodeRelationships,
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TvShowEpisodeAttributes {
pub source: TvShowSource,
pub language: Language,
pub episode_number: u64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub air_date: Option<chrono::NaiveDate>,
pub name: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub overview: Option<String>,
pub production_code: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub still_url: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub duration: Option<u64>,
pub vote_average: f64,
pub vote_count: u64,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TvShowEpisodeRelationships {
pub tvshow: Relation<TvShowEntity>,
pub season: Relation<TvShowSeasonEntity>,
pub progress: Relation<TvShowEpisodeProgressEntity>,
pub files: Relation<Vec<MediaFileEntity>>,
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[cfg_attr(feature = "facet", repr(C))]
#[derive(Clone, Debug, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub enum TvShowEpisodeField {
#[default]
AirDate,
SeasonNumber,
}
impl AsStr for TvShowEpisodeField {
fn as_str(&self) -> &str {
match self {
Self::AirDate => "air_date",
Self::SeasonNumber => "season_numbers",
}
}
}
impl std::str::FromStr for TvShowEpisodeField {
type Err = crate::entity::prelude::ParseEnumError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"air_date" => Ok(Self::AirDate),
"season_numbers" => Ok(Self::SeasonNumber),
other => Err(crate::entity::prelude::ParseEnumError::new(other)),
}
}
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[cfg_attr(feature = "facet", repr(C))]
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, serde::Deserialize, serde::Serialize)]
pub enum TvShowEpisodeInclude {
#[default]
#[serde(rename = "media-file")]
MediaFile,
#[serde(rename = "tvshow")]
TvShow,
#[serde(rename = "tvshow-season")]
TvShowSeason,
#[serde(rename = "tvshow-episode-progress")]
TvShowEpisodeProgress,
}
impl AsStr for TvShowEpisodeInclude {
fn as_str(&self) -> &str {
match self {
Self::MediaFile => "media-file",
Self::TvShow => "tvshow",
Self::TvShowSeason => "tvshow-season",
Self::TvShowEpisodeProgress => "tvshow-episode-progress",
}
}
}
impl std::str::FromStr for TvShowEpisodeInclude {
type Err = crate::entity::prelude::ParseEnumError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"media-file" => Ok(Self::MediaFile),
"tvshow" => Ok(Self::TvShow),
"tvshow-season" => Ok(Self::TvShowSeason),
"tvshow-episode-progress" => Ok(Self::TvShowEpisodeProgress),
other => Err(crate::entity::prelude::ParseEnumError::new(other)),
}
}
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[cfg_attr(feature = "facet", repr(C))]
#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase", untagged)]
pub enum TvShowEpisodeRelation {
MediaFile(MediaFileDocument),
TvShow(TvShowDocument),
TvShowSeason(TvShowSeasonDocument),
TvShowEpisodeProgress(TvShowEpisodeProgressDocument),
}
crate::create_kind!(TvShowEpisodeProgressKind, "tvshow-episode-progresses");
pub type TvShowEpisodeProgressEntity = Entity<Couple, TvShowEpisodeProgressKind>;
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
pub struct TvShowEpisodeProgressInputDocument {
pub id: Couple,
#[serde(rename = "type")]
pub kind: TvShowEpisodeProgressKind,
pub attributes: TvShowEpisodeProgressInputAttributes,
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TvShowEpisodeProgressInputAttributes {
pub progress: u64,
pub completed: bool,
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
pub struct TvShowEpisodeProgressDocument {
pub id: Couple,
#[serde(rename = "type")]
pub kind: TvShowEpisodeProgressKind,
pub attributes: TvShowEpisodeProgressAttributes,
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TvShowEpisodeProgressAttributes {
pub progress: u64,
pub completed: bool,
pub created_at: chrono::DateTime<chrono::Utc>,
pub updated_at: chrono::DateTime<chrono::Utc>,
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, Default, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ListTvShowEpisodeFilter {
#[serde(default)]
pub subscribed: Option<bool>,
#[serde(default)]
pub watched: Option<bool>,
}
impl ListTvShowEpisodeFilter {
pub const fn is_empty(&self) -> bool {
self.subscribed.is_none() && self.watched.is_none()
}
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ListTvShowEpisodeParams {
#[serde(default, skip_serializing_if = "ListTvShowEpisodeFilter::is_empty")]
pub filter: ListTvShowEpisodeFilter,
#[serde(default, skip_serializing_if = "HashSet::is_empty")]
pub include: HashSet<TvShowEpisodeInclude>,
#[serde(default)]
pub sort: Sort<TvShowEpisodeField>,
#[serde(default, skip_serializing_if = "Page::is_default")]
pub page: Page,
}