use axum::routing::get;
use entertainarr_domain::tvshow::entity::{
FindTvShowSeasonResponse, ListTvShowSeasonResponse, TvShowSeason,
};
use crate::entity::tvshow::{TvShowDocument, TvShowEntity, TvShowRelationships};
use crate::entity::tvshow_season::{
TvShowSeasonAttributes, TvShowSeasonDocument, TvShowSeasonField, TvShowSeasonInclude,
TvShowSeasonRelation, TvShowSeasonRelationships,
};
use crate::entity::tvshow_subscription::TvShowSubscriptionEntity;
use crate::entity::{ApiResource, Couple, Entity, Relation};
use crate::server::handler::prelude::FromDomainResponse;
mod find;
mod list_by_tvshow;
pub fn create<S>() -> axum::Router<S>
where
S: crate::server::prelude::ServerState + Clone,
{
axum::Router::new()
.route("/tvshow-seasons/{season_id}", get(find::handle::<S>))
.route(
"/tvshows/{tvshow_id}/seasons",
get(list_by_tvshow::handle::<S>),
)
}
impl From<entertainarr_domain::tvshow::entity::TvShowSeasonField> for TvShowSeasonField {
fn from(value: entertainarr_domain::tvshow::entity::TvShowSeasonField) -> Self {
match value {
entertainarr_domain::tvshow::entity::TvShowSeasonField::SeasonNumber => {
Self::SeasonNumber
}
}
}
}
impl From<TvShowSeasonField> for entertainarr_domain::tvshow::entity::TvShowSeasonField {
fn from(value: TvShowSeasonField) -> Self {
match value {
TvShowSeasonField::SeasonNumber => Self::SeasonNumber,
}
}
}
impl From<TvShowSeason> for TvShowSeasonAttributes {
fn from(value: TvShowSeason) -> Self {
TvShowSeasonAttributes {
source: value.source.into(),
season_number: value.season_number,
air_date: value.air_date,
language: value.language.into(),
name: value.name,
overview: value.overview,
poster_url: value.poster_url,
created_at: value.created_at,
updated_at: value.updated_at,
}
}
}
impl From<TvShowSeason> for TvShowSeasonDocument {
fn from(value: TvShowSeason) -> Self {
TvShowSeasonDocument {
id: value.id,
kind: Default::default(),
relationships: TvShowSeasonRelationships {
tvshow: Relation {
data: Some(TvShowEntity::new(value.tvshow_id)),
meta: (),
},
},
attributes: value.into(),
}
}
}
impl FromDomainResponse<FindTvShowSeasonResponse, TvShowSeasonInclude>
for ApiResource<TvShowSeasonDocument, TvShowSeasonRelation>
{
fn from_response(
response: FindTvShowSeasonResponse,
required: std::collections::HashSet<TvShowSeasonInclude>,
) -> Self {
let data = TvShowSeasonDocument {
id: response.season.id,
kind: Default::default(),
relationships: TvShowSeasonRelationships {
tvshow: Relation {
data: Some(TvShowEntity::new(response.tvshow.id)),
meta: (),
},
},
attributes: response.season.into(),
};
let mut includes = Vec::with_capacity(1);
if required.contains(&TvShowSeasonInclude::TvShow) {
includes.push(TvShowSeasonRelation::TvShow(TvShowDocument {
id: response.tvshow.id,
kind: Default::default(),
relationships: TvShowRelationships {
subscription: Relation {
data: response.subscription.map(|sub| {
TvShowSubscriptionEntity::new(Couple(sub.tvshow_id, sub.user_id))
}),
meta: (),
},
},
attributes: response.tvshow.into(),
}));
}
ApiResource { data, includes }
}
}
impl FromDomainResponse<ListTvShowSeasonResponse, TvShowSeasonInclude>
for ApiResource<Vec<TvShowSeasonDocument>, TvShowSeasonRelation>
{
fn from_response(
response: ListTvShowSeasonResponse,
required: std::collections::HashSet<TvShowSeasonInclude>,
) -> Self {
let data = response
.seasons
.into_iter()
.map(|season| {
let tvshow = response.tvshows.get(&season.tvshow_id);
TvShowSeasonDocument {
id: season.id,
kind: Default::default(),
relationships: TvShowSeasonRelationships {
tvshow: Relation {
data: tvshow.map(|t| TvShowEntity::new(t.id)),
meta: (),
},
},
attributes: season.into(),
}
})
.collect();
let mut includes = Vec::new();
if required.contains(&TvShowSeasonInclude::TvShow) {
includes.extend(response.tvshows.into_values().map(|tvshow| {
TvShowSeasonRelation::TvShow(TvShowDocument {
id: tvshow.id,
kind: Default::default(),
relationships: TvShowRelationships {
subscription: Relation {
data: response
.subscriptions
.get(&tvshow.id)
.map(|sub| Entity::new(Couple(sub.tvshow_id, sub.user_id))),
meta: (),
},
},
attributes: tvshow.into(),
})
}));
}
ApiResource { data, includes }
}
}