use std::ops::{Deref, DerefMut};
use crate::traits::{FetchFrom, Refetchable};
use crate::http::routes::Route;
use crate::util::{fetch_route, a_fetch_route};
use serde::{self, Serialize, Deserialize};
use crate::error::Result;
#[cfg(feature = "async")]
use async_trait::async_trait;
use crate::http::Client;
use super::common::StarPower;
#[cfg(feature = "players")]
use super::players::{
player::PlayerBrawlerStat,
battlelog::BattleBrawler,
};
use crate::Brawlers;
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub struct BrawlerList {
#[serde(default)]
pub items: Vec<Brawler>
}
impl Deref for BrawlerList {
type Target = Vec<Brawler>;
fn deref(&self) -> &Vec<Brawler> {
&self.items
}
}
impl DerefMut for BrawlerList {
fn deref_mut(&mut self) -> &mut Vec<Brawler> {
&mut self.items
}
}
impl BrawlerList {
pub fn get_route() -> Route {
Route::Brawlers
}
pub fn fetch(client: &Client) -> Result<BrawlerList> {
let route = BrawlerList::get_route();
fetch_route::<BrawlerList>(client, &route)
}
#[cfg(feature = "async")]
pub async fn a_fetch(client: &Client) -> Result<BrawlerList> {
let route = BrawlerList::get_route();
a_fetch_route::<BrawlerList>(client, &route).await
}
}
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Brawler {
#[serde(default)]
pub name: String,
#[serde(default)]
pub id: usize,
#[serde(default)]
pub star_powers: Vec<StarPower>,
}
impl Default for Brawler {
fn default() -> Brawler {
Brawler {
name: String::from(""),
id: 0,
star_powers: vec![]
}
}
}
impl Brawler {
pub fn get_fetch_prop(&self) -> usize { self.id }
pub fn get_route(id: usize) -> Route { Route::Brawler(id) }
pub fn fetch(client: &Client, id: usize) -> Result<Brawler> {
let route = Brawler::get_route(id);
fetch_route::<Brawler>(client, &route)
}
#[cfg(feature="async")]
pub async fn a_fetch(client: &Client, id: usize) -> Result<Brawler> {
let route = Brawler::get_route(id);
a_fetch_route::<Brawler>(client, &route).await
}
}
#[cfg_attr(feature = "async", async_trait)]
impl Refetchable for Brawler {
fn refetch(&self, client: &Client) -> Result<Brawler> {
Brawler::fetch(client, self.id)
}
#[cfg(feature = "async")]
async fn a_refetch(&self, client: &Client) -> Result<Brawler> {
Brawler::a_fetch(client, self.id).await
}
}
#[cfg_attr(feature = "async", async_trait)]
#[cfg(feature = "players")]
impl FetchFrom<PlayerBrawlerStat> for Brawler {
fn fetch_from(client: &Client, p_brawler: &PlayerBrawlerStat) -> Result<Brawler> {
Brawler::fetch(client, p_brawler.id)
}
#[cfg(feature = "async")]
async fn a_fetch_from(client: &Client, p_brawler: &PlayerBrawlerStat) -> Result<Brawler> {
Brawler::a_fetch(client, p_brawler.id).await
}
}
#[cfg_attr(feature = "async", async_trait)]
#[cfg(feature = "players")]
impl FetchFrom<BattleBrawler> for Brawler {
fn fetch_from(client: &Client, b_brawler: &BattleBrawler) -> Result<Brawler> {
Brawler::fetch(client, b_brawler.id)
}
#[cfg(feature = "async")]
async fn a_fetch_from(client: &Client, b_brawler: &BattleBrawler) -> Result<Brawler> {
Brawler::a_fetch(client, b_brawler.id).await
}
}
#[cfg_attr(feature = "async", async_trait)]
impl FetchFrom<Brawlers> for Brawler {
fn fetch_from(client: &Client, b_brawler: &Brawlers) -> Result<Brawler> {
Brawler::fetch(client, b_brawler.to_owned() as usize)
}
#[cfg(feature = "async")]
async fn a_fetch_from(client: &Client, b_brawler: &Brawlers) -> Result<Brawler> {
Brawler::a_fetch(client, b_brawler.to_owned() as usize).await
}
}
#[cfg(test)]
mod tests {
use serde_json;
use super::{BrawlerList, Brawler};
use super::super::common::StarPower;
use crate::error::Error;
#[test]
fn brawlers_deser() -> Result<(), Box<dyn ::std::error::Error>> {
let brawlers_json_s = r##"{
"items": [
{
"id": 16000000,
"name": "SHELLY",
"starPowers": [
{
"id": 23000076,
"name": "Shell Shock"
},
{
"id": 23000135,
"name": "Band-Aid"
}
]
},
{
"id": 16000001,
"name": "COLT",
"starPowers": [
{
"id": 23000077,
"name": "Slick Boots"
},
{
"id": 23000138,
"name": "Magnum Special"
}
]
},
{
"id": 16000002,
"name": "BULL",
"starPowers": [
{
"id": 23000078,
"name": "Berserker"
},
{
"id": 23000137,
"name": "Tough Guy"
}
]
},
{
"id": 16000003,
"name": "BROCK",
"starPowers": [
{
"id": 23000079,
"name": "Incendiary"
},
{
"id": 23000150,
"name": "Rocket No. Four"
}
]
}
]
}"##;
let brawlers = serde_json::from_str::<BrawlerList>(brawlers_json_s)
.map_err(Error::Json)?;
assert_eq!(
brawlers,
BrawlerList {
items: vec![
Brawler {
id: 16000000,
name: String::from("SHELLY"),
star_powers: vec![
StarPower {
id: 23000076,
name: String::from("Shell Shock")
},
StarPower {
id: 23000135,
name: String::from("Band-Aid")
}
]
},
Brawler {
id: 16000001,
name: String::from("COLT"),
star_powers: vec![
StarPower {
id: 23000077,
name: String::from("Slick Boots")
},
StarPower {
id: 23000138,
name: String::from("Magnum Special")
}
]
},
Brawler {
id: 16000002,
name: String::from("BULL"),
star_powers: vec![
StarPower {
id: 23000078,
name: String::from("Berserker")
},
StarPower {
id: 23000137,
name: String::from("Tough Guy")
}
]
},
Brawler {
id: 16000003,
name: String::from("BROCK"),
star_powers: vec![
StarPower {
id: 23000079,
name: String::from("Incendiary")
},
StarPower {
id: 23000150,
name: String::from("Rocket No. Four")
}
]
}
]
}
);
Ok(())
}
#[test]
fn brawler_deser() -> Result<(), Box<dyn ::std::error::Error>> {
let brawler_json_s = r##"{
"id": 16000000,
"name": "SHELLY",
"starPowers": [
{
"id": 23000076,
"name": "Shell Shock"
},
{
"id": 23000135,
"name": "Band-Aid"
}
]
}"##;
let brawler = serde_json::from_str::<Brawler>(brawler_json_s)
.map_err(Error::Json)?;
assert_eq!(
brawler,
Brawler {
id: 16000000,
name: String::from("SHELLY"),
star_powers: vec![
StarPower {
id: 23000076,
name: String::from("Shell Shock")
},
StarPower {
id: 23000135,
name: String::from("Band-Aid")
}
]
}
);
Ok(())
}
}