use std::collections::HashSet;
use crate::entity::{
Couple, Entity,
prelude::{AsStr, Page, Sort},
};
crate::create_kind!(PodcastEpisodeKind, "podcast-episodes");
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PodcastEpisodeDocument {
pub id: u64,
#[serde(rename = "type")]
pub kind: PodcastEpisodeKind,
pub attributes: PodcastEpisodeAttributes,
pub relationships: PodcastEpisodeRelationships,
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PodcastEpisodeAttributes {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub guid: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub published_at: Option<chrono::DateTime<chrono::Utc>>,
pub title: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub link: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub duration: Option<u64>,
pub file_url: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub file_size: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub file_type: Option<String>,
pub created_at: chrono::DateTime<chrono::Utc>,
pub updated_at: chrono::DateTime<chrono::Utc>,
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[cfg_attr(feature = "facet", repr(C))]
#[derive(Clone, Debug, Default, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub enum PodcastEpisodeField {
#[default]
PublishedAt,
}
impl AsStr for PodcastEpisodeField {
fn as_str(&self) -> &str {
match self {
Self::PublishedAt => "published_at",
}
}
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[cfg_attr(feature = "facet", repr(C))]
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "kebab-case")]
pub enum PodcastEpisodeInclude {
#[default]
Podcast,
PodcastEpisodeProgress,
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[cfg_attr(feature = "facet", repr(C))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(untagged)]
pub enum PodcastEpisodeRelation {
Podcast(super::podcast::PodcastDocument),
PodcastEpisodeProgress(PodcastEpisodeProgressDocument),
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
pub struct PodcastEpisodeRelationships {
pub podcast: super::Relation<super::podcast::PodcastEntity>,
pub progress: super::Relation<PodcastEpisodeProgressEntity>,
}
crate::create_kind!(PodcastEpisodeProgressKind, "podcast-episode-progresses");
pub type PodcastEpisodeProgressEntity = Entity<Couple, PodcastEpisodeProgressKind>;
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
pub struct PodcastEpisodeProgressInputDocument {
pub id: Couple,
#[serde(rename = "type")]
pub kind: PodcastEpisodeProgressKind,
pub attributes: PodcastEpisodeProgressInputAttributes,
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PodcastEpisodeProgressInputAttributes {
pub progress: u64,
pub completed: bool,
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
pub struct PodcastEpisodeProgressDocument {
pub id: Couple,
#[serde(rename = "type")]
pub kind: PodcastEpisodeProgressKind,
pub attributes: PodcastEpisodeProgressAttributes,
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PodcastEpisodeProgressAttributes {
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 ListPodcastEpisodeFilter {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub filtered: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub subscribed: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub watched: Option<bool>,
}
impl ListPodcastEpisodeFilter {
pub const fn is_default(&self) -> bool {
self.filtered.is_none() && self.subscribed.is_none() && self.watched.is_none()
}
}
#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, Default, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ListPodcastEpisodeParams {
#[serde(default, skip_serializing_if = "ListPodcastEpisodeFilter::is_default")]
pub filter: ListPodcastEpisodeFilter,
#[serde(default, skip_serializing_if = "HashSet::is_empty")]
pub include: HashSet<PodcastEpisodeInclude>,
#[serde(default, skip_serializing_if = "Sort::is_default")]
pub sort: Sort<PodcastEpisodeField>,
#[serde(default, skip_serializing_if = "Page::is_default")]
pub page: Page,
}
#[derive(Debug)]
pub struct ParsePodcastEpisodeFieldError;
impl std::fmt::Display for ParsePodcastEpisodeFieldError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("invalid podcast episode field")
}
}
impl std::str::FromStr for PodcastEpisodeField {
type Err = ParsePodcastEpisodeFieldError;
fn from_str(input: &str) -> Result<Self, Self::Err> {
match input {
"published_at" => Ok(Self::PublishedAt),
_ => Err(ParsePodcastEpisodeFieldError),
}
}
}