pokerust 0.3.1

Pokeapi wrapper
Documentation
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};

use super::get_api_loc_from_url;
use super::utility::{APIResource, NamedAPIResource};

use crate::cache::get_resource;

/// <https://pokeapi.co/docs/v2#un-named>
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "deny_unknown_fields", serde(deny_unknown_fields))]
#[non_exhaustive]
pub struct APIResourceList<T> {
    pub count: u64,
    pub next: Option<String>,
    pub previous: Option<String>,
    pub results: Vec<APIResource<T>>,
}

/// <https://pokeapi.co/docs/v2#named>
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "deny_unknown_fields", serde(deny_unknown_fields))]
#[non_exhaustive]
pub struct NamedAPIResourceList<T> {
    pub count: u64,
    pub next: Option<String>,
    pub previous: Option<String>,
    pub results: Vec<NamedAPIResource<T>>,
}

/// Trait for lists of `(Named)APIResources`
pub trait List
where
    Self: Sized,
{
    /// Get the number of items in this list
    fn count(&self) -> &u64;

    /// Get the next list
    ///
    /// # Errors
    ///
    /// Will return an Err if there is an issue contacting the API endpoint on an uncached route
    fn next_list(&self) -> Result<Option<Self>, minreq::Error>;

    /// Get the previous list
    ///
    /// # Errors
    ///
    /// Will return an Err if there is an issue contacting the API endpoint on an uncached route
    fn previous_list(&self) -> Result<Option<Self>, minreq::Error>;
}

// impl<T> List for NamedAPIResourceList<T>
// where
//     T: DeserializeOwned
// {
//     fn count(&self) -> &u64 {
//         &self.count
//     }
//
//     fn next_list(&self) -> Result<Option<Self>, minreq::Error> {
//         if let Some(loc) = &self.next {
//             let list = get_resource(get_api_loc_from_url(&loc))?.json::<Self>()?;
//             Ok(Some(list))
//         } else {
//             Ok(None)
//         }
//     }
//
//     fn previous_list(&self) -> Result<Option<Self>, minreq::Error> {
//         if let Some(loc) = &self.next {
//             let list = get_resource(get_api_loc_from_url(&loc))?.json::<Self>()?;
//             Ok(Some(list))
//         } else {
//             Ok(None)
//         }
//     }
// }

macro_rules! impl_list {
    { $A:tt } => {
impl<T> List for $A<T>
where
    T: DeserializeOwned,
{
    fn count(&self) -> &u64 {
        &self.count
    }

    fn next_list(&self) -> Result<Option<Self>, minreq::Error> {
        if let Some(loc) = &self.next {
            let list = get_resource(get_api_loc_from_url(&loc))?.json::<Self>()?;
            Ok(Some(list))
        } else {
            Ok(None)
        }
    }

    fn previous_list(&self) -> Result<Option<Self>, minreq::Error> {
        if let Some(loc) = &self.next {
            let list = get_resource(get_api_loc_from_url(&loc))?.json::<Self>()?;
            Ok(Some(list))
        } else {
            Ok(None)
        }
    }
}
}
}

impl_list! {APIResourceList}
impl_list! {NamedAPIResourceList}