entertainarr-adapter-http 0.1.1

HTTP adapter for entertainarr
Documentation
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,
}