pub mod characters;
use std::collections::HashMap;
use std::fmt::{self, Formatter};
use std::num::NonZeroU8;
use chrono::{DateTime, Utc};
use serde::de::{Error, MapAccess, SeqAccess, Visitor};
use serde::ser::{SerializeMap, SerializeSeq};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::{Authentication, ClientExecutor, RequestBuilder};
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Account {
pub id: String,
pub age: u64,
pub name: String,
pub world: u64,
pub guilds: Vec<String>,
pub guild_leader: Option<Vec<String>>,
pub created: DateTime<Utc>,
pub access: AccountAccess,
pub commander: bool,
pub fractal_level: Option<u8>,
pub daily_ap: Option<u16>,
pub monthly_ap: Option<u16>,
pub wvw_rank: Option<u16>,
pub last_modified: DateTime<Utc>,
pub build_storage_slots: Option<u64>,
}
impl Account {
const URI: &'static str = "/v2/account";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct AccountAccess(u8);
impl AccountAccess {
const NONE: u8 = 1 << 0;
const PLAY_FOR_FREE: u8 = 1 << 1;
const GUILD_WARS_2: u8 = 1 << 2;
const HEART_OF_THORNS: u8 = 1 << 3;
const PATH_OF_FIRE: u8 = 1 << 4;
const END_OF_DRAGONS: u8 = 1 << 5;
const NONE_STR: &'static str = "None";
const PLAY_FOR_FREE_STR: &'static str = "PlayForFree";
const GUILD_WARS_2_STR: &'static str = "GuildWars2";
const HEART_OF_THORNS_STR: &'static str = "HeartOfThorns";
const PATH_OF_FIRE_STR: &'static str = "PathOfFire";
const END_OF_DRAGONS_STR: &'static str = "EndOfDragons";
#[inline]
fn len(&self) -> usize {
self.0.count_ones() as usize
}
#[inline]
pub fn none(&self) -> bool {
self.0 & Self::NONE != 0
}
#[inline]
pub fn play_for_free(&self) -> bool {
self.0 & Self::PLAY_FOR_FREE != 0
}
#[inline]
pub fn guild_wars_2(&self) -> bool {
self.0 & Self::GUILD_WARS_2 != 0
}
#[inline]
pub fn heart_of_thorns(&self) -> bool {
self.0 & Self::HEART_OF_THORNS != 0
}
#[inline]
pub fn path_of_fire(&self) -> bool {
self.0 & Self::PATH_OF_FIRE != 0
}
#[inline]
pub fn end_of_dragons(&self) -> bool {
self.0 & Self::END_OF_DRAGONS != 0
}
}
impl Serialize for AccountAccess {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut seq = serializer.serialize_seq(Some(self.len()))?;
if self.play_for_free() {
seq.serialize_element(Self::PLAY_FOR_FREE_STR)?;
}
if self.guild_wars_2() {
seq.serialize_element(Self::GUILD_WARS_2_STR)?;
}
if self.heart_of_thorns() {
seq.serialize_element(Self::HEART_OF_THORNS_STR)?;
}
if self.path_of_fire() {
seq.serialize_element(Self::PATH_OF_FIRE_STR)?;
}
if self.end_of_dragons() {
seq.serialize_element(Self::END_OF_DRAGONS_STR)?;
}
seq.end()
}
}
impl<'de> Deserialize<'de> for AccountAccess {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct AccountAccessVisitor;
impl<'de> Visitor<'de> for AccountAccessVisitor {
type Value = AccountAccess;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("a sequence of access strings")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut state = 0;
loop {
let elem = seq.next_element::<&str>()?;
match elem {
Some(AccountAccess::NONE_STR) => {
state |= AccountAccess::NONE;
}
Some(AccountAccess::PLAY_FOR_FREE_STR) => {
state |= AccountAccess::PLAY_FOR_FREE;
}
Some(AccountAccess::GUILD_WARS_2_STR) => {
state |= AccountAccess::GUILD_WARS_2;
}
Some(AccountAccess::HEART_OF_THORNS_STR) => {
state |= AccountAccess::HEART_OF_THORNS;
}
Some(AccountAccess::PATH_OF_FIRE_STR) => {
state |= AccountAccess::PATH_OF_FIRE;
}
Some(AccountAccess::END_OF_DRAGONS_STR) => {
state |= AccountAccess::END_OF_DRAGONS;
}
Some(_) => return Err(A::Error::custom("invalid account access")),
None => return Ok(AccountAccess(state)),
}
}
}
}
deserializer.deserialize_seq(AccountAccessVisitor)
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(transparent)]
pub struct AccountAchievements(pub Vec<AccountAchievement>);
impl AccountAchievements {
const URI: &'static str = "/v2/account/achievements";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountAchievement {
pub id: u64,
pub bits: Option<Vec<u64>>,
pub current: Option<u64>,
pub max: Option<u64>,
pub done: bool,
pub repeated: Option<u64>,
pub unlocked: Option<bool>,
}
impl AccountAchievement {
#[inline]
pub fn is_unlocked(&self) -> bool {
self.unlocked.unwrap_or(true)
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(transparent)]
pub struct AccountBank(pub Vec<Option<BankItem>>);
impl AccountBank {
const URI: &'static str = "/v2/account/bank";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct BankItem {
pub id: u64,
pub count: u16,
pub charges: Option<u64>,
pub skin: Option<u64>,
pub dyes: Option<Vec<u64>>,
pub upgrades: Option<Vec<u64>>,
pub upgrade_slot_indices: Option<Vec<u64>>,
pub infusions: Option<Vec<u64>>,
pub binding: Option<ItemBinding>,
pub bound_to: Option<String>,
pub stats: Option<Vec<ItemStats>>,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum ItemBinding {
Account,
Character,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ItemStats {
pub id: u64,
pub attributes: HashMap<String, f64>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(transparent)]
pub struct AccountDailyCrafting(pub Vec<String>);
impl AccountDailyCrafting {
const URI: &'static str = "/v2/account/dailycrafting";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountDungeons(pub Vec<String>);
impl AccountDungeons {
const URI: &'static str = "/v2/account/dungeons";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(transparent)]
pub struct AccountDyes(pub Vec<u64>);
impl AccountDyes {
const URI: &'static str = "/v2/account/dyes";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(transparent)]
pub struct AccountFinishers(pub Vec<AccountFinisher>);
impl AccountFinishers {
const URI: &'static str = "/v2/account/finishers";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountFinisher {
pub id: u64,
#[serde(default = "AccountFinisher::serde_default_permanent")]
pub permanent: bool,
#[serde(default)]
pub quantity: u64,
}
impl AccountFinisher {
#[inline]
fn serde_default_permanent() -> bool {
true
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(transparent)]
pub struct AccountGliders(pub Vec<u64>);
impl AccountGliders {
const URI: &'static str = "/v2/account/gliders";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(transparent)]
pub struct AccountHomeCats(pub Vec<u64>);
impl AccountHomeCats {
const URI: &'static str = "/v2/account/home/cats";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(transparent)]
pub struct AccountHomeNodes(pub Vec<String>);
impl AccountHomeNodes {
const URI: &'static str = "/v2/account/home/nodes";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(transparent)]
pub struct AccountInventory(pub Vec<Option<InventoryItem>>);
impl AccountInventory {
const URI: &'static str = "/v2/account/inventory";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct InventoryItem {
pub id: u64,
pub count: u64,
pub charges: Option<u64>,
pub skin: Option<u64>,
pub upgrades: Option<Vec<u64>>,
pub infusions: Option<Vec<u64>>,
pub binding: ItemBinding,
}
pub struct AccountLuck(pub u64);
impl AccountLuck {
const URI: &'static str = "/v2/account/luck";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
impl Serialize for AccountLuck {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
struct Map(u64);
impl Serialize for Map {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut map = serializer.serialize_map(Some(2))?;
map.serialize_entry("id", "luck")?;
map.serialize_entry("value", &self.0)?;
map.end()
}
}
let len = if self.0 == 0 { 0 } else { 1 };
let mut seq = serializer.serialize_seq(Some(len))?;
if self.0 != 0 {
seq.serialize_element(&Map(self.0))?;
}
seq.end()
}
}
impl<'de> Deserialize<'de> for AccountLuck {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct LuckVisitor;
impl<'de> Visitor<'de> for LuckVisitor {
type Value = AccountLuck;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a sequence with one or zero elements")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
struct Map(AccountLuck);
impl<'de> Deserialize<'de> for Map {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct LuckMapVisitor;
impl<'de> Visitor<'de> for LuckMapVisitor {
type Value = Map;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a map containing account luck")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let value;
match map.next_key::<&str>()? {
Some(key) => match key {
"id" => match map.next_value()? {
Some("luck") => (),
_ => {
return Err(A::Error::custom(
"expected a luck id value",
))
}
},
_ => {
return Err(A::Error::custom(
"expected a luck id value",
))
}
},
None => {
return Err(A::Error::custom("missing fields id, value"))
}
}
match map.next_key::<&str>()? {
Some(key) => match key {
"value" => match map.next_value()? {
Some(val) => value = val,
None => {
return Err(A::Error::custom("expected a value"))
}
},
_ => return Err(A::Error::custom("expected a value")),
},
None => return Err(A::Error::custom("missing fields value")),
}
Ok(Map(AccountLuck(value)))
}
}
deserializer.deserialize_map(LuckMapVisitor)
}
}
match seq.next_element::<Map>()? {
Some(map) => Ok(map.0),
None => Ok(AccountLuck(0)),
}
}
}
deserializer.deserialize_seq(LuckVisitor)
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountLegendaryArmory(Vec<LegendaryArmoryItem>);
impl AccountLegendaryArmory {
const URI: &'static str = "/v2/account/legendaryarmory";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct LegendaryArmoryItem {
pub id: u64,
pub count: NonZeroU8,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountMailCarriers(pub Vec<u64>);
impl AccountMailCarriers {
const URI: &'static str = "/v2/account/mailcarriers";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountMapChests(Vec<String>);
impl AccountMapChests {
const URI: &'static str = "/v2/account/mapchests";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountMasteries(pub Vec<AccountMastery>);
impl AccountMasteries {
const URI: &'static str = "/v2/account/masteries";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountMastery {
pub id: u64,
pub level: u8,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountMasteryPoints {
pub totals: Vec<RegionMasteryPoints>,
pub unlocked: Vec<u64>,
}
impl AccountMasteryPoints {
const URI: &'static str = "/v2/account/mastery/points";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RegionMasteryPoints {
pub region: String,
pub spent: u64,
pub earned: u64,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountMaterials(Vec<AccountMaterial>);
impl AccountMaterials {
const URI: &'static str = "/v2/account/materials";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountMaterial {
pub id: u64,
pub category: u8,
pub binding: Option<ItemBinding>,
pub count: u16,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountMinis(pub Vec<u64>);
impl AccountMinis {
const URI: &'static str = "/v2/account/minis";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountMountSkins(pub Vec<u64>);
impl AccountMountSkins {
const URI: &'static str = "/v2/account/mounts/skins";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountMountTypes(pub Vec<String>);
impl AccountMountTypes {
const URI: &'static str = "/v2/account/mounts/types";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountNovelties(pub Vec<u64>);
impl AccountNovelties {
const URI: &'static str = "/v2/account/novelties";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountOutfits(pub Vec<u64>);
impl AccountOutfits {
const URI: &'static str = "/v2/account/outfits";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountProgression(pub Vec<AccountProgressionItem>);
impl AccountProgression {
const URI: &'static str = "/v2/account/progression";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountProgressionItem {
pub id: String,
pub value: u64,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountPvPHeroes(pub Vec<u64>);
impl AccountPvPHeroes {
const URI: &'static str = "/v2/account/pvp/heroes";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountRaids(pub Vec<String>);
impl AccountRaids {
const URI: &'static str = "/v2/account/raids";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountRecipes(pub Vec<u64>);
impl AccountRecipes {
const URI: &'static str = "/v2/account/recipes";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountSkins(pub Vec<u64>);
impl AccountSkins {
const URI: &'static str = "/v2/account/skins";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountTitles(pub Vec<u64>);
impl AccountTitles {
const URI: &'static str = "/v2/account/titles";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountWallet(pub Vec<AccountCurrency>);
impl AccountWallet {
const URI: &'static str = "/v2/account/wallet";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountCurrency {
pub id: u64,
pub value: u64,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AccountWorldBosses(pub Vec<String>);
impl AccountWorldBosses {
const URI: &'static str = "/v2/account/worldbosses";
pub fn get<C>(client: &C) -> C::Result
where
C: ClientExecutor<Self>,
{
client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
}
}