use std::marker::PhantomData;
use reqwest::Url;
use serde::de::DeserializeOwned;
use crate::{client::RustemonClient, error::Error};
use super::{
encounters::{EncounterConditionValue, EncounterMethod},
games::{Generation, Version, VersionGroup},
utility::Language,
};
#[derive(Default, Debug, Clone, PartialEq, serde::Deserialize)]
pub struct NamedApiResourceList<T> {
pub count: Option<i64>,
pub next: Option<String>,
pub previous: Option<String>,
pub results: Option<Vec<NamedApiResource<T>>>,
}
#[derive(Default, Debug, Clone, PartialEq, serde::Deserialize)]
pub struct ApiResource {
pub url: Option<String>,
}
#[derive(Default, Debug, Clone, PartialEq, serde::Deserialize)]
pub struct Description {
pub description: Option<String>,
pub language: Option<NamedApiResource<Language>>,
}
#[derive(Default, Debug, Clone, PartialEq, serde::Deserialize)]
pub struct Effect {
pub effect: Option<String>,
pub language: Option<NamedApiResource<Language>>,
}
#[derive(Default, Debug, Clone, PartialEq, serde::Deserialize)]
pub struct Encounter {
pub min_level: Option<i64>,
pub max_level: Option<i64>,
pub condition_values: Option<Vec<NamedApiResource<EncounterConditionValue>>>,
pub chance: Option<i64>,
pub method: Option<NamedApiResource<EncounterMethod>>,
}
#[derive(Default, Debug, Clone, PartialEq, serde::Deserialize)]
pub struct FlavorText {
pub flavor_text: Option<String>,
pub language: Option<NamedApiResource<Language>>,
pub version: Option<NamedApiResource<Version>>,
}
#[derive(Default, Debug, Clone, PartialEq, serde::Deserialize)]
pub struct GenerationGameIndex {
pub game_index: Option<i64>,
pub generation: Option<NamedApiResource<Generation>>,
}
#[derive(Default, Debug, Clone, PartialEq, serde::Deserialize)]
pub struct MachineVersionDetail {
pub machine: Option<ApiResource>,
pub version_group: Option<NamedApiResource<VersionGroup>>,
}
#[derive(Default, Debug, Clone, PartialEq, serde::Deserialize)]
pub struct Name {
pub name: Option<String>,
pub language: Option<NamedApiResource<Language>>,
}
#[derive(Default, Debug, Clone, PartialEq, serde::Deserialize)]
pub struct VerboseEffect {
pub effect: Option<String>,
pub short_effect: Option<String>,
pub language: Option<NamedApiResource<Language>>,
}
#[derive(Default, Debug, Clone, PartialEq, serde::Deserialize)]
pub struct VersionEncounterDetail {
pub version: Option<NamedApiResource<Version>>,
pub max_chance: Option<i64>,
pub encounter_details: Option<Vec<Encounter>>,
}
#[derive(Default, Debug, Clone, PartialEq, serde::Deserialize)]
pub struct VersionGameIndex {
pub game_index: Option<i64>,
pub version: Option<NamedApiResource<Version>>,
}
#[derive(Default, Debug, Clone, PartialEq, serde::Deserialize)]
pub struct VersionGroupFlavorText {
pub text: Option<String>,
pub language: Option<NamedApiResource<Language>>,
pub version_group: Option<NamedApiResource<VersionGroup>>,
}
#[derive(Default, Debug, Clone, PartialEq, serde::Deserialize)]
pub struct NamedApiResource<T> {
pub name: Option<String>,
pub url: Option<String>,
#[serde(skip)]
_marker: PhantomData<T>,
}
impl<T> NamedApiResource<T> {
pub async fn follow(&self, rustemon_client: &RustemonClient) -> Result<T, Error>
where
T: DeserializeOwned,
{
match &self.url {
Some(url_str) => {
let url = Url::parse(url_str).unwrap();
rustemon_client.get_by_url::<T>(url).await
}
None => Err(Error::FollowEmptyURL),
}
}
}