use serde::{Deserialize, Serialize};
use serde_json::Value;
use super::{
Character, Cover, Date, Format, Link, Person, Relation, Season, Source, Status, Studio, Tag,
Title,
};
use crate::{Client, Result};
#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize)]
#[serde(rename_all(deserialize = "camelCase"))]
pub struct Anime {
pub id: i64,
pub id_mal: Option<i64>,
pub title: Title,
pub format: Format,
pub status: Status,
pub description: String,
pub start_date: Option<Date>,
pub end_date: Option<Date>,
pub season: Option<Season>,
pub season_year: Option<u32>,
pub season_int: Option<u64>,
pub episodes: Option<u16>,
pub duration: Option<u8>,
pub country_of_origin: Option<String>,
pub is_licensed: Option<bool>,
pub source: Option<Source>,
pub hashtag: Option<String>,
pub updated_at: Option<u64>,
#[serde(rename = "coverImage")]
pub cover: Cover,
#[serde(rename = "bannerImage")]
pub banner: Option<String>,
pub genres: Option<Vec<String>>,
pub synonyms: Option<Vec<String>>,
pub average_score: Option<u8>,
pub mean_score: Option<u8>,
pub popularity: Option<u32>,
pub is_locked: Option<bool>,
pub trending: Option<u32>,
pub favourites: Option<u32>,
pub tags: Option<Vec<Tag>>,
pub(crate) relations: Value,
pub(crate) characters: Value,
#[serde(skip)]
pub staff: Option<Vec<Person>>,
#[serde(skip)]
pub studios: Option<Vec<Studio>>,
pub is_favourite: Option<bool>,
pub is_favourite_blocked: Option<bool>,
pub is_adult: bool,
pub next_airing_episode: Option<AiringSchedule>,
pub external_links: Option<Vec<Link>>,
pub streaming_episodes: Option<Vec<Link>>,
#[serde(rename = "siteUrl")]
pub url: String,
#[serde(skip)]
pub(crate) client: Client,
#[serde(default)]
pub(crate) is_full_loaded: bool,
}
impl Anime {
pub async fn load_full(self) -> Result<Self> {
if !self.is_full_loaded {
self.client.get_anime(self.id).await
} else {
panic!("This anime is already full loaded!")
}
}
pub fn characters(&self) -> Vec<Character> {
let edges = self
.characters
.as_object()
.unwrap()
.get("edges")
.unwrap()
.as_array()
.unwrap()
.iter()
.map(|e| e.as_object().unwrap())
.collect::<Vec<_>>();
let mut characters = Vec::with_capacity(edges.len());
for edge in edges {
let node = edge.get("node").unwrap();
let role = edge.get("role").unwrap().as_str().unwrap();
let mut character = serde_json::from_value::<Character>(node.clone()).unwrap();
character.role = Some(role.into());
characters.push(character);
}
characters
}
pub fn relations(&self) -> Vec<Relation> {
self.relations
.as_object()
.unwrap()
.get("edges")
.unwrap()
.as_array()
.unwrap()
.iter()
.map(|r| serde_json::from_value(r.clone()).unwrap())
.collect()
}
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct AiringSchedule {
pub id: u32,
#[serde(rename = "airingAt")]
pub at: i64,
#[serde(rename = "timeUntilAiring")]
pub time_until: u64,
pub episode: u32,
}