gw2api_rs/v2/account.rs
1//! Exposes details about player accounts. All endpoints in this module required authentication.
2pub mod characters;
3
4use std::collections::HashMap;
5use std::fmt::{self, Formatter};
6use std::num::NonZeroU8;
7
8use chrono::{DateTime, Utc};
9use serde::de::{Error, MapAccess, SeqAccess, Visitor};
10use serde::ser::{SerializeMap, SerializeSeq};
11use serde::{Deserialize, Deserializer, Serialize, Serializer};
12
13use crate::{Authentication, ClientExecutor, RequestBuilder};
14
15/// Basic information about an account.
16#[derive(Clone, Debug, Serialize, Deserialize)]
17pub struct Account {
18 /// A globally unique GUID for the account.
19 pub id: String,
20 /// The age of the account in seconds.
21 pub age: u64,
22 /// The unique display name of the account. Note that it is possible for the name to
23 /// change.
24 pub name: String,
25 /// The home world of the account.
26 pub world: u64,
27 /// A list of guilds the account has joined.
28 pub guilds: Vec<String>,
29 /// A list of guilds the account has leader access to.
30 ///
31 /// **Requires the `guilds` scope.** This is `None` if the scope is missing.
32 pub guild_leader: Option<Vec<String>>,
33 /// The account creation date.
34 pub created: DateTime<Utc>,
35 /// A list of content the account has access to.
36 pub access: AccountAccess,
37 /// Whether the account has unlocked the commander tag.
38 pub commander: bool,
39 /// The fractal level of the account.
40 ///
41 /// **Requires the `progression` scope.** This is `None` if the scope is missing.
42 pub fractal_level: Option<u8>,
43 /// The number of daily achievement points unlocked by the account.
44 ///
45 /// **Requires the `progression` scope.** This is `None` if the scope is missing.
46 pub daily_ap: Option<u16>,
47 /// The number of monthly achievement points unlocked by the account.
48 ///
49 /// **Requires the `progression` scope.** This is `None` if the scope is missing.
50 pub monthly_ap: Option<u16>,
51 /// The WvW rank of the account.
52 ///
53 /// **Requires the `progression` scope.** This is `None` if the scope is missing.
54 pub wvw_rank: Option<u16>,
55 /// The date when the account information was last changed.
56 pub last_modified: DateTime<Utc>,
57 /// The amount of build storage slots unlocked by the account.
58 ///
59 /// **Requires the `builds` scope.** This is `None` if the scope is missing.
60 pub build_storage_slots: Option<u64>,
61}
62
63impl Account {
64 const URI: &'static str = "/v2/account";
65
66 /// Returns the information about the currently authenticated account.
67 ///
68 /// # Authentication
69 ///
70 /// This endpoint requires authentication and returns an [`Error`] if no access token is set.
71 /// When authenticated it returns information about the account of the current access token.
72 ///
73 /// # Examples
74 ///
75 /// ```no_run
76 /// # use gw2api_rs::{Client, Result};
77 /// # use gw2api_rs::v2::account::Account;
78 /// #
79 /// # async fn run() -> Result<()> {
80 /// # let token = "";
81 /// let client: Client = Client::builder().access_token(token).into();
82 /// let account = Account::get(&client).await?;
83 /// println!("{:?}", account);
84 /// # Ok(())
85 /// # }
86 /// ```
87 ///
88 /// Using the [`blocking`] client:
89 ///
90 /// ```no_run
91 /// # use gw2api_rs::Result;
92 /// # use gw2api_rs::blocking::Client;
93 /// # use gw2api_rs::v2::account::Account;
94 /// #
95 /// # fn run() -> Result<()> {
96 /// # let token = "";
97 /// let client: Client = Client::builder().access_token(token).into();
98 /// let account = Account::get(&client)?;
99 /// println!("{:?}", account);
100 /// # Ok(())
101 /// # }
102 /// ```
103 ///
104 /// [`Error`]: struct@crate::Error
105 /// [`blocking`]: crate::blocking
106 pub fn get<C>(client: &C) -> C::Result
107 where
108 C: ClientExecutor<Self>,
109 {
110 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
111 }
112}
113
114/// A list of content an [`Account`] has access to.
115#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
116pub struct AccountAccess(u8);
117
118impl AccountAccess {
119 const NONE: u8 = 1 << 0;
120 const PLAY_FOR_FREE: u8 = 1 << 1;
121 const GUILD_WARS_2: u8 = 1 << 2;
122 const HEART_OF_THORNS: u8 = 1 << 3;
123 const PATH_OF_FIRE: u8 = 1 << 4;
124 const END_OF_DRAGONS: u8 = 1 << 5;
125
126 const NONE_STR: &'static str = "None";
127 const PLAY_FOR_FREE_STR: &'static str = "PlayForFree";
128 const GUILD_WARS_2_STR: &'static str = "GuildWars2";
129 const HEART_OF_THORNS_STR: &'static str = "HeartOfThorns";
130 const PATH_OF_FIRE_STR: &'static str = "PathOfFire";
131 const END_OF_DRAGONS_STR: &'static str = "EndOfDragons";
132
133 #[inline]
134 fn len(&self) -> usize {
135 self.0.count_ones() as usize
136 }
137
138 /// Returns `true` if the account has no access.
139 ///
140 /// Note that this probably shouldn't ever happen.
141 #[inline]
142 pub fn none(&self) -> bool {
143 self.0 & Self::NONE != 0
144 }
145
146 /// Returns `true` if the account has free to play access.
147 #[inline]
148 pub fn play_for_free(&self) -> bool {
149 self.0 & Self::PLAY_FOR_FREE != 0
150 }
151
152 /// Returns `true` if the account has access to the base game of Guild Wars 2.
153 #[inline]
154 pub fn guild_wars_2(&self) -> bool {
155 self.0 & Self::GUILD_WARS_2 != 0
156 }
157
158 /// Returns `true` if the account has access to the Heart of Thorns expansion.
159 #[inline]
160 pub fn heart_of_thorns(&self) -> bool {
161 self.0 & Self::HEART_OF_THORNS != 0
162 }
163
164 /// Returns `true` if the account has access to the Path of Fire expansion.
165 #[inline]
166 pub fn path_of_fire(&self) -> bool {
167 self.0 & Self::PATH_OF_FIRE != 0
168 }
169
170 /// Returns `true` if the account has access to the End of Dragons expansion.
171 #[inline]
172 pub fn end_of_dragons(&self) -> bool {
173 self.0 & Self::END_OF_DRAGONS != 0
174 }
175}
176
177impl Serialize for AccountAccess {
178 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
179 where
180 S: Serializer,
181 {
182 let mut seq = serializer.serialize_seq(Some(self.len()))?;
183
184 // if self.none() {
185 // seq.serialize_element(Self::NONE_STR)?;
186 // }
187
188 if self.play_for_free() {
189 seq.serialize_element(Self::PLAY_FOR_FREE_STR)?;
190 }
191
192 if self.guild_wars_2() {
193 seq.serialize_element(Self::GUILD_WARS_2_STR)?;
194 }
195
196 if self.heart_of_thorns() {
197 seq.serialize_element(Self::HEART_OF_THORNS_STR)?;
198 }
199
200 if self.path_of_fire() {
201 seq.serialize_element(Self::PATH_OF_FIRE_STR)?;
202 }
203
204 if self.end_of_dragons() {
205 seq.serialize_element(Self::END_OF_DRAGONS_STR)?;
206 }
207
208 seq.end()
209 }
210}
211
212impl<'de> Deserialize<'de> for AccountAccess {
213 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
214 where
215 D: Deserializer<'de>,
216 {
217 struct AccountAccessVisitor;
218
219 impl<'de> Visitor<'de> for AccountAccessVisitor {
220 type Value = AccountAccess;
221
222 fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
223 formatter.write_str("a sequence of access strings")
224 }
225
226 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
227 where
228 A: SeqAccess<'de>,
229 {
230 let mut state = 0;
231
232 loop {
233 let elem = seq.next_element::<&str>()?;
234
235 match elem {
236 Some(AccountAccess::NONE_STR) => {
237 state |= AccountAccess::NONE;
238 }
239 Some(AccountAccess::PLAY_FOR_FREE_STR) => {
240 state |= AccountAccess::PLAY_FOR_FREE;
241 }
242 Some(AccountAccess::GUILD_WARS_2_STR) => {
243 state |= AccountAccess::GUILD_WARS_2;
244 }
245 Some(AccountAccess::HEART_OF_THORNS_STR) => {
246 state |= AccountAccess::HEART_OF_THORNS;
247 }
248 Some(AccountAccess::PATH_OF_FIRE_STR) => {
249 state |= AccountAccess::PATH_OF_FIRE;
250 }
251 Some(AccountAccess::END_OF_DRAGONS_STR) => {
252 state |= AccountAccess::END_OF_DRAGONS;
253 }
254 Some(_) => return Err(A::Error::custom("invalid account access")),
255 None => return Ok(AccountAccess(state)),
256 }
257 }
258 }
259 }
260
261 deserializer.deserialize_seq(AccountAccessVisitor)
262 }
263}
264
265/// A list of achievements unlocked by the account.
266#[derive(Clone, Debug, Serialize, Deserialize)]
267#[serde(transparent)]
268pub struct AccountAchievements(pub Vec<AccountAchievement>);
269
270impl AccountAchievements {
271 const URI: &'static str = "/v2/account/achievements";
272
273 /// Returns a list of achievements unlocked by the currently authenticated account.
274 ///
275 /// # Authentication
276 ///
277 /// This endpoint requires authentication and returns an [`Error`] if no access token is set.
278 /// When authenticated it returns a list of achievements unlocked by the account of the current
279 /// access token.
280 ///
281 /// # Examples
282 ///
283 /// ```no_run
284 /// # use gw2api_rs::{Client, Result};
285 /// # use gw2api_rs::v2::account::AccountAchievements;
286 /// #
287 /// # async fn run() -> Result<()> {
288 /// # let token = "";
289 /// let client: Client = Client::builder().access_token(token).into();
290 /// let achievements = AccountAchievements::get(&client).await?;
291 /// println!("{:?}", achievements);
292 /// # Ok(())
293 /// # }
294 /// ```
295 ///
296 /// Using the [`blocking`] client:
297 ///
298 /// ```no_run
299 /// # use gw2api_rs::Result;
300 /// # use gw2api_rs::blocking::Client;
301 /// # use gw2api_rs::v2::account::AccountAchievements;
302 /// #
303 /// # fn run() -> Result<()> {
304 /// # let token = "";
305 /// let client: Client = Client::builder().access_token(token).into();
306 /// let achievements = AccountAchievements::get(&client)?;
307 /// println!("{:?}", achievements);
308 /// # Ok(())
309 /// # }
310 /// ```
311 ///
312 /// [`Error`]: struct@crate::Error
313 /// [`blocking`]: crate::blocking
314 pub fn get<C>(client: &C) -> C::Result
315 where
316 C: ClientExecutor<Self>,
317 {
318 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
319 }
320}
321
322/// An achievement unlocked by an account.
323#[derive(Clone, Debug, Serialize, Deserialize)]
324pub struct AccountAchievement {
325 /// The id of the achievement.
326 pub id: u64,
327 pub bits: Option<Vec<u64>>,
328 /// The current progress towards the achievement.
329 pub current: Option<u64>,
330 /// The amount if objectives required to complete the achievement.
331 pub max: Option<u64>,
332 /// Whether the achievement has been completed.
333 pub done: bool,
334 /// The number of times this achievement has been completed. Only avaliable for repeatable
335 /// achievements.
336 pub repeated: Option<u64>,
337 /// Whether the achievement has been unlocked (not completed).
338 ///
339 /// Note that a `None` value also indicates that the achievment is unlocked.
340 pub unlocked: Option<bool>,
341}
342
343impl AccountAchievement {
344 /// Returns `true` if this achievement is unlocked.
345 #[inline]
346 pub fn is_unlocked(&self) -> bool {
347 self.unlocked.unwrap_or(true)
348 }
349}
350
351/// A list of items stored in the account's bank/vault.
352#[derive(Clone, Debug, Serialize, Deserialize)]
353#[serde(transparent)]
354pub struct AccountBank(pub Vec<Option<BankItem>>);
355
356impl AccountBank {
357 const URI: &'static str = "/v2/account/bank";
358
359 /// Returns a list of items stored in the account's bank.
360 ///
361 /// # Authentication
362 ///
363 /// This endpoint requires authentication and returns an [`Error`] if no access token is set.
364 /// When authenticated it returns the account's bank of the current access token.
365 ///
366 /// # Examples
367 ///
368 /// ```no_run
369 /// # use gw2api_rs::{Client, Result};
370 /// # use gw2api_rs::v2::account::AccountBank;
371 /// #
372 /// # async fn run() -> Result<()> {
373 /// # let token = "";
374 /// let client: Client = Client::builder().access_token(token).into();
375 /// let bank = AccountBank::get(&client).await?;
376 /// # Ok(())
377 /// # }
378 /// ```
379 ///
380 /// Using the [`blocking`] client:
381 ///
382 /// ```no_run
383 /// # use gw2api_rs::Result;
384 /// # use gw2api_rs::blocking::Client;
385 /// # use gw2api_rs::v2::account::AccountBank;
386 /// #
387 /// # fn run() -> Result<()> {
388 /// # let token = "";
389 /// let client: Client = Client::builder().access_token(token).into();
390 /// let bank = AccountBank::get(&client)?;
391 /// # Ok(())
392 /// # }
393 /// ```
394 ///
395 /// [`Error`]: struct@crate::Error
396 /// [`blocking`]: crate::blocking
397 pub fn get<C>(client: &C) -> C::Result
398 where
399 C: ClientExecutor<Self>,
400 {
401 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
402 }
403}
404
405/// A single item stored in an [`AccountBank`].
406#[derive(Clone, Debug, Serialize, Deserialize)]
407pub struct BankItem {
408 /// The id of the item.
409 pub id: u64,
410 /// The number of items stored on this stack.
411 pub count: u16,
412 /// The number of charges remaining on this item. Only avaliable for some items.
413 pub charges: Option<u64>,
414 /// The id of the skin applied on this item. Only avaliable for some items.
415 pub skin: Option<u64>,
416 /// A list of ids of dyes applied on this item. Only avaliable for some items.
417 pub dyes: Option<Vec<u64>>,
418 /// A list of upgrades applied on this item. Only avaliable for some items.
419 pub upgrades: Option<Vec<u64>>,
420 pub upgrade_slot_indices: Option<Vec<u64>>,
421 /// A list of infusions applied on this item. Only avaliable for some items.
422 pub infusions: Option<Vec<u64>>,
423 /// Whom the item is bound to. If `None` the item is not bound at all.
424 pub binding: Option<ItemBinding>,
425 /// The name of the character the item is bound to. Only avaliable if `binding` is
426 /// `Character`.
427 pub bound_to: Option<String>,
428 pub stats: Option<Vec<ItemStats>>,
429}
430
431#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
432pub enum ItemBinding {
433 Account,
434 Character,
435}
436
437#[derive(Clone, Debug, Serialize, Deserialize)]
438pub struct ItemStats {
439 pub id: u64,
440 pub attributes: HashMap<String, f64>,
441}
442
443/// A list of items that have been crafted by the account since daily reset.
444#[derive(Clone, Debug, Serialize, Deserialize)]
445#[serde(transparent)]
446pub struct AccountDailyCrafting(pub Vec<String>);
447
448impl AccountDailyCrafting {
449 const URI: &'static str = "/v2/account/dailycrafting";
450
451 /// Returns a list of items that have been crafted by the currently authenticated account since
452 /// daily reset.
453 ///
454 /// # Authentication
455 ///
456 /// This endpoint requires authentication and returns an [`Error`] if no access token is set.
457 /// When authenticated it returns a list of items crafted by the account of the current access
458 /// token.
459 ///
460 /// # Examples
461 ///
462 /// ```no_run
463 /// # use gw2api_rs::{Client, Result};
464 /// # use gw2api_rs::v2::account::AccountDailyCrafting;
465 /// #
466 /// # async fn run() -> Result<()> {
467 /// # let token = "";
468 /// let client: Client = Client::builder().access_token(token).into();
469 /// let items = AccountDailyCrafting::get(&client).await?;
470 /// # Ok(())
471 /// # }
472 /// ```
473 ///
474 /// Using the [`blocking`] client:
475 ///
476 /// ```no_run
477 /// # use gw2api_rs::Result;
478 /// # use gw2api_rs::blocking::Client;
479 /// # use gw2api_rs::v2::account::AccountDailyCrafting;
480 /// #
481 /// # fn run() -> Result<()> {
482 /// # let token = "";
483 /// let client: Client = Client::builder().access_token(token).into();
484 /// let items = AccountDailyCrafting::get(&client)?;
485 /// # Ok(())
486 /// # }
487 /// ```
488 ///
489 /// [`Error`]: struct@crate::Error
490 /// [`blocking`]: crate::blocking
491 pub fn get<C>(client: &C) -> C::Result
492 where
493 C: ClientExecutor<Self>,
494 {
495 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
496 }
497}
498
499/// A list of dungeon paths completed since daily reset.
500#[derive(Clone, Debug, Serialize, Deserialize)]
501pub struct AccountDungeons(pub Vec<String>);
502
503impl AccountDungeons {
504 const URI: &'static str = "/v2/account/dungeons";
505
506 /// Returns a list of dungeon paths completed by the currently authenticatd account since the
507 /// daily reset.
508 ///
509 /// # Authentication
510 ///
511 /// This endpoint requires authentication and returns an [`Error`] if no access token is set.
512 /// When authenticated it returns a list of dungeon paths completed by the account of the
513 /// current access token.
514 ///
515 /// # Examples
516 ///
517 /// ```no_run
518 /// # use gw2api_rs::{Client, Result};
519 /// # use gw2api_rs::v2::account::AccountDungeons;
520 /// #
521 /// # async fn run() -> Result<()> {
522 /// # let token = "";
523 /// let client: Client = Client::builder().access_token(token).into();
524 /// let paths = AccountDungeons::get(&client).await?;
525 /// # Ok(())
526 /// # }
527 /// ```
528 ///
529 /// Using the [`blocking`] client:
530 ///
531 /// ```no_run
532 /// # use gw2api_rs::Result;
533 /// # use gw2api_rs::blocking::Client;
534 /// # use gw2api_rs::v2::account::AccountDungeons;
535 /// #
536 /// # fn run() -> Result<()> {
537 /// # let token = "";
538 /// let client: Client = Client::builder().access_token(token).into();
539 /// let paths = AccountDungeons::get(&client)?;
540 /// # Ok(())
541 /// # }
542 /// ```
543 ///
544 /// [`Error`]: struct@crate::Error
545 /// [`blocking`]: crate::blocking
546 pub fn get<C>(client: &C) -> C::Result
547 where
548 C: ClientExecutor<Self>,
549 {
550 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
551 }
552}
553
554/// A list of dyes unlocked by an account.
555#[derive(Clone, Debug, Serialize, Deserialize)]
556#[serde(transparent)]
557pub struct AccountDyes(pub Vec<u64>);
558
559impl AccountDyes {
560 const URI: &'static str = "/v2/account/dyes";
561
562 /// Returns a list of dyes unlocked by the currently authenticated account.
563 ///
564 /// # Authentication
565 ///
566 /// This endpoint requires authentication and returns an [`Error`] if no access token is set.
567 /// When authenticated it returns the dyes unlocked by the account of the current access token.
568 ///
569 /// # Examples
570 ///
571 /// ```no_run
572 /// # use gw2api_rs::{Client, Result};
573 /// # use gw2api_rs::v2::account::AccountDyes;
574 /// #
575 /// # async fn run() -> Result<()> {
576 /// # let token = "";
577 /// let client: Client = Client::builder().access_token(token).into();
578 /// let dyes = AccountDyes::get(&client).await?;
579 /// # Ok(())
580 /// # }
581 /// ```
582 ///
583 /// Using the [`blocking`] client:
584 ///
585 /// ```no_run
586 /// # use gw2api_rs::Result;
587 /// # use gw2api_rs::blocking::Client;
588 /// # use gw2api_rs::v2::account::AccountDyes;
589 /// #
590 /// # fn run() -> Result<()> {
591 /// # let token = "";
592 /// let client: Client = Client::builder().access_token(token).into();
593 /// let dyes = AccountDyes::get(&client)?;
594 /// # Ok(())
595 /// # }
596 /// ```
597 ///
598 /// [`Error`]: struct@crate::Error
599 /// [`blocking`]: crate::blocking
600 pub fn get<C>(client: &C) -> C::Result
601 where
602 C: ClientExecutor<Self>,
603 {
604 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
605 }
606}
607
608/// A list of finishers unlocked.
609#[derive(Clone, Debug, Serialize, Deserialize)]
610#[serde(transparent)]
611pub struct AccountFinishers(pub Vec<AccountFinisher>);
612
613impl AccountFinishers {
614 const URI: &'static str = "/v2/account/finishers";
615
616 /// Returns a list of finishers unlocked by the currently authenticated account.
617 ///
618 /// # Authentication
619 ///
620 /// This endpoint requires authentication and returns an [`Error`] if no access token is set.
621 /// When authenticated it returns a list of finishers unlocked by the account of the current
622 /// access token.
623 ///
624 /// # Examples
625 ///
626 /// ```no_run
627 /// # use gw2api_rs::{Client, Result};
628 /// # use gw2api_rs::v2::account::AccountFinishers;
629 /// #
630 /// # async fn run() -> Result<()> {
631 /// # let token = "";
632 /// let client: Client = Client::builder().access_token(token).into();
633 /// let finishers = AccountFinishers::get(&client).await?;
634 /// # Ok(())
635 /// # }
636 /// ```
637 ///
638 /// Using the [`blocking`] client:
639 ///
640 /// ```no_run
641 /// # use gw2api_rs::Result;
642 /// # use gw2api_rs::blocking::Client;
643 /// # use gw2api_rs::v2::account::AccountFinishers;
644 /// #
645 /// # fn run() -> Result<()> {
646 /// # let token = "";
647 /// let client: Client = Client::builder().access_token(token).into();
648 /// let finishers = AccountFinishers::get(&client)?;
649 /// # Ok(())
650 /// # }
651 /// ```
652 ///
653 /// [`Error`]: struct@crate::Error
654 /// [`blocking`]: crate::blocking
655 pub fn get<C>(client: &C) -> C::Result
656 where
657 C: ClientExecutor<Self>,
658 {
659 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
660 }
661}
662
663/// A single finisher unlocked by an account.
664#[derive(Clone, Debug, Serialize, Deserialize)]
665pub struct AccountFinisher {
666 /// The id of the finisher.
667 pub id: u64,
668 /// Whether the finisher is unlocked permanently.
669 #[serde(default = "AccountFinisher::serde_default_permanent")]
670 pub permanent: bool,
671 /// The number of uses remaining if `permanent` is `false`.
672 ///
673 /// This field is always `0` if `permanent` is `true`.
674 #[serde(default)]
675 pub quantity: u64,
676}
677
678impl AccountFinisher {
679 #[inline]
680 fn serde_default_permanent() -> bool {
681 true
682 }
683}
684
685/// A list of gliders unlocked by an account.
686#[derive(Clone, Debug, Serialize, Deserialize)]
687#[serde(transparent)]
688pub struct AccountGliders(pub Vec<u64>);
689
690impl AccountGliders {
691 const URI: &'static str = "/v2/account/gliders";
692
693 /// Returns a list of gliders unlocked by the currently authenticated account.
694 ///
695 /// # Authentication
696 ///
697 /// This endpoint requires authentication and returns an [`Error`] if no access token is set.
698 /// When authenticated it returns a list of gliders unlocked by the account of the current
699 /// access token.
700 ///
701 /// # Examples
702 ///
703 /// ```no_run
704 /// # use gw2api_rs::{Client, Result};
705 /// # use gw2api_rs::v2::account::AccountGliders;
706 /// #
707 /// # async fn run() -> Result<()> {
708 /// # let token = "";
709 /// let client: Client = Client::builder().access_token(token).into();
710 /// let gliders = AccountGliders::get(&client).await?;
711 /// # Ok(())
712 /// # }
713 /// ```
714 ///
715 /// Using the [`blocking`] client:
716 ///
717 /// ```no_run
718 /// # use gw2api_rs::Result;
719 /// # use gw2api_rs::blocking::Client;
720 /// # use gw2api_rs::v2::account::AccountGliders;
721 /// #
722 /// # fn run() -> Result<()> {
723 /// # let token = "";
724 /// let client: Client = Client::builder().access_token(token).into();
725 /// let gliders = AccountGliders::get(&client)?;
726 /// # Ok(())
727 /// # }
728 /// ```
729 ///
730 /// [`Error`]: struct@crate::Error
731 /// [`blocking`]: crate::blocking
732 pub fn get<C>(client: &C) -> C::Result
733 where
734 C: ClientExecutor<Self>,
735 {
736 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
737 }
738}
739
740/// A list of home cats unlocked by an account.
741#[derive(Clone, Debug, Serialize, Deserialize)]
742#[serde(transparent)]
743pub struct AccountHomeCats(pub Vec<u64>);
744
745impl AccountHomeCats {
746 const URI: &'static str = "/v2/account/home/cats";
747
748 /// Returns a list of home cats unlocked by the currently authenticated account.
749 ///
750 /// # Authentication
751 ///
752 /// This endpoint requires authentication and returns an [`Error`] if no access token is set.
753 /// When authenticated it returns a list of home cats unlocked by the account of the current
754 /// access token.
755 ///
756 /// # Examples
757 ///
758 /// ```no_run
759 /// # use gw2api_rs::{Client, Result};
760 /// # use gw2api_rs::v2::account::AccountHomeCats;
761 /// #
762 /// # async fn run() -> Result<()> {
763 /// # let token = "";
764 /// let client: Client = Client::builder().access_token(token).into();
765 /// let cats = AccountHomeCats::get(&client).await?;
766 /// # Ok(())
767 /// # }
768 /// ```
769 ///
770 /// Using the [`blocking`] client:
771 ///
772 /// ```no_run
773 /// # use gw2api_rs::Result;
774 /// # use gw2api_rs::blocking::Client;
775 /// # use gw2api_rs::v2::account::AccountHomeCats;
776 /// #
777 /// # fn run() -> Result<()> {
778 /// # let token = "";
779 /// let client: Client = Client::builder().access_token(token).into();
780 /// let cats = AccountHomeCats::get(&client)?;
781 /// # Ok(())
782 /// # }
783 /// ```
784 ///
785 /// [`Error`]: struct@crate::Error
786 /// [`blocking`]: crate::blocking
787 pub fn get<C>(client: &C) -> C::Result
788 where
789 C: ClientExecutor<Self>,
790 {
791 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
792 }
793}
794
795/// A list of home nodes unlocked by an account.
796#[derive(Clone, Debug, Serialize, Deserialize)]
797#[serde(transparent)]
798pub struct AccountHomeNodes(pub Vec<String>);
799
800impl AccountHomeNodes {
801 const URI: &'static str = "/v2/account/home/nodes";
802
803 /// Returns a list of home nodes unlocked by the currently authenticated account.
804 ///
805 /// # Authentication
806 ///
807 /// This endpoint requires authentication and returns an [`Error`] if no access token is set.
808 /// When authenticated it returns a list of home nodes unlocked by the account of the current
809 /// access token.
810 ///
811 /// # Examples
812 ///
813 /// ```no_run
814 /// # use gw2api_rs::{Client, Result};
815 /// # use gw2api_rs::v2::account::AccountHomeNodes;
816 /// #
817 /// # async fn run() -> Result<()> {
818 /// # let token = "";
819 /// let client: Client = Client::builder().access_token(token).into();
820 /// let nodes = AccountHomeNodes::get(&client).await?;
821 /// # Ok(())
822 /// # }
823 /// ```
824 ///
825 /// Using the [`blocking`] client:
826 ///
827 /// ```no_run
828 /// # use gw2api_rs::Result;
829 /// # use gw2api_rs::blocking::Client;
830 /// # use gw2api_rs::v2::account::AccountHomeNodes;
831 /// #
832 /// # fn run() -> Result<()> {
833 /// # let token = "";
834 /// let client: Client = Client::builder().access_token(token).into();
835 /// let nodes = AccountHomeNodes::get(&client)?;
836 /// # Ok(())
837 /// # }
838 /// ```
839 ///
840 /// [`Error`]: struct@crate::Error
841 /// [`blocking`]: crate::blocking
842 pub fn get<C>(client: &C) -> C::Result
843 where
844 C: ClientExecutor<Self>,
845 {
846 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
847 }
848}
849
850/// A list of items stored in the shared inventory slots of an account.
851///
852/// A `None` value indicates an empty slot.
853#[derive(Clone, Debug, Serialize, Deserialize)]
854#[serde(transparent)]
855pub struct AccountInventory(pub Vec<Option<InventoryItem>>);
856
857impl AccountInventory {
858 const URI: &'static str = "/v2/account/inventory";
859
860 /// Returns a list of items stored in the shared inventory slots of the currently authenticated
861 /// account.
862 ///
863 /// # Authentication
864 ///
865 /// This endpoint requires authentication and returns an [`Error`] if no access token is set.
866 /// When authenticated it returns a list of item stored in the shared inventory slots of the
867 /// account of the current access token.
868 ///
869 /// # Examples
870 ///
871 /// ```no_run
872 /// # use gw2api_rs::{Client, Result};
873 /// # use gw2api_rs::v2::account::AccountInventory;
874 /// #
875 /// # async fn run() -> Result<()> {
876 /// # let token = "";
877 /// let client: Client = Client::builder().access_token(token).into();
878 /// let inventory = AccountInventory::get(&client).await?;
879 /// # Ok(())
880 /// # }
881 /// ```
882 ///
883 /// Using the [`blocking`] client:
884 ///
885 /// ```no_run
886 /// # use gw2api_rs::Result;
887 /// # use gw2api_rs::blocking::Client;
888 /// # use gw2api_rs::v2::account::AccountInventory;
889 /// #
890 /// # fn run() -> Result<()> {
891 /// # let token = "";
892 /// let client: Client = Client::builder().access_token(token).into();
893 /// let inventory = AccountInventory::get(&client)?;
894 /// # Ok(())
895 /// # }
896 /// ```
897 ///
898 /// [`Error`]: struct@crate::Error
899 /// [`blocking`]: crate::blocking
900 pub fn get<C>(client: &C) -> C::Result
901 where
902 C: ClientExecutor<Self>,
903 {
904 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
905 }
906}
907
908#[derive(Clone, Debug, Serialize, Deserialize)]
909pub struct InventoryItem {
910 pub id: u64,
911 pub count: u64,
912 pub charges: Option<u64>,
913 pub skin: Option<u64>,
914 pub upgrades: Option<Vec<u64>>,
915 pub infusions: Option<Vec<u64>>,
916 pub binding: ItemBinding,
917}
918
919/// The current luck value of an account.
920pub struct AccountLuck(pub u64);
921
922impl AccountLuck {
923 const URI: &'static str = "/v2/account/luck";
924
925 /// Returns the unlocked luck value of the currently authenticated account.
926 ///
927 /// # Authentication
928 ///
929 /// This endpoint requires authentication and returns an [`Error`] if no access token is set.
930 /// When authenticated it returns unlocked luck value of the account of the current access
931 /// token.
932 ///
933 /// # Examples
934 ///
935 /// ```no_run
936 /// # use gw2api_rs::{Client, Result};
937 /// # use gw2api_rs::v2::account::AccountLuck;
938 /// #
939 /// # async fn run() -> Result<()> {
940 /// # let token = "";
941 /// let client: Client = Client::builder().access_token(token).into();
942 /// let luck = AccountLuck::get(&client).await?;
943 /// # Ok(())
944 /// # }
945 /// ```
946 ///
947 /// Using the [`blocking`] client:
948 ///
949 /// ```no_run
950 /// # use gw2api_rs::Result;
951 /// # use gw2api_rs::blocking::Client;
952 /// # use gw2api_rs::v2::account::AccountLuck;
953 /// #
954 /// # fn run() -> Result<()> {
955 /// # let token = "";
956 /// let client: Client = Client::builder().access_token(token).into();
957 /// let luck = AccountLuck::get(&client)?;
958 /// # Ok(())
959 /// # }
960 /// ```
961 ///
962 /// [`Error`]: struct@crate::Error
963 /// [`blocking`]: crate::blocking
964 pub fn get<C>(client: &C) -> C::Result
965 where
966 C: ClientExecutor<Self>,
967 {
968 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
969 }
970}
971
972impl Serialize for AccountLuck {
973 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
974 where
975 S: Serializer,
976 {
977 struct Map(u64);
978
979 impl Serialize for Map {
980 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
981 where
982 S: Serializer,
983 {
984 let mut map = serializer.serialize_map(Some(2))?;
985 map.serialize_entry("id", "luck")?;
986 map.serialize_entry("value", &self.0)?;
987 map.end()
988 }
989 }
990
991 let len = if self.0 == 0 { 0 } else { 1 };
992
993 let mut seq = serializer.serialize_seq(Some(len))?;
994
995 if self.0 != 0 {
996 seq.serialize_element(&Map(self.0))?;
997 }
998
999 seq.end()
1000 }
1001}
1002
1003impl<'de> Deserialize<'de> for AccountLuck {
1004 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1005 where
1006 D: Deserializer<'de>,
1007 {
1008 struct LuckVisitor;
1009
1010 impl<'de> Visitor<'de> for LuckVisitor {
1011 type Value = AccountLuck;
1012
1013 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1014 write!(formatter, "a sequence with one or zero elements")
1015 }
1016
1017 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
1018 where
1019 A: SeqAccess<'de>,
1020 {
1021 struct Map(AccountLuck);
1022
1023 impl<'de> Deserialize<'de> for Map {
1024 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1025 where
1026 D: Deserializer<'de>,
1027 {
1028 struct LuckMapVisitor;
1029
1030 impl<'de> Visitor<'de> for LuckMapVisitor {
1031 type Value = Map;
1032
1033 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1034 write!(formatter, "a map containing account luck")
1035 }
1036
1037 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
1038 where
1039 A: MapAccess<'de>,
1040 {
1041 let value;
1042
1043 match map.next_key::<&str>()? {
1044 Some(key) => match key {
1045 "id" => match map.next_value()? {
1046 Some("luck") => (),
1047 _ => {
1048 return Err(A::Error::custom(
1049 "expected a luck id value",
1050 ))
1051 }
1052 },
1053 _ => {
1054 return Err(A::Error::custom(
1055 "expected a luck id value",
1056 ))
1057 }
1058 },
1059 None => {
1060 return Err(A::Error::custom("missing fields id, value"))
1061 }
1062 }
1063
1064 match map.next_key::<&str>()? {
1065 Some(key) => match key {
1066 "value" => match map.next_value()? {
1067 Some(val) => value = val,
1068 None => {
1069 return Err(A::Error::custom("expected a value"))
1070 }
1071 },
1072 _ => return Err(A::Error::custom("expected a value")),
1073 },
1074 None => return Err(A::Error::custom("missing fields value")),
1075 }
1076
1077 Ok(Map(AccountLuck(value)))
1078 }
1079 }
1080
1081 deserializer.deserialize_map(LuckMapVisitor)
1082 }
1083 }
1084
1085 match seq.next_element::<Map>()? {
1086 Some(map) => Ok(map.0),
1087 None => Ok(AccountLuck(0)),
1088 }
1089 }
1090 }
1091
1092 deserializer.deserialize_seq(LuckVisitor)
1093 }
1094}
1095
1096/// A list of legendary items unlocked in the account armory.
1097#[derive(Clone, Debug, Serialize, Deserialize)]
1098pub struct AccountLegendaryArmory(Vec<LegendaryArmoryItem>);
1099
1100impl AccountLegendaryArmory {
1101 const URI: &'static str = "/v2/account/legendaryarmory";
1102
1103 pub fn get<C>(client: &C) -> C::Result
1104 where
1105 C: ClientExecutor<Self>,
1106 {
1107 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
1108 }
1109}
1110
1111/// An item in unlocked in the legendary armory.
1112#[derive(Clone, Debug, Serialize, Deserialize)]
1113pub struct LegendaryArmoryItem {
1114 /// The id of the legendary item.
1115 pub id: u64,
1116 /// The number of items unlocked. This value is in the range of 1 to 4.
1117 pub count: NonZeroU8,
1118}
1119
1120/// A list of unlocked mail carriers.
1121#[derive(Clone, Debug, Serialize, Deserialize)]
1122pub struct AccountMailCarriers(pub Vec<u64>);
1123
1124impl AccountMailCarriers {
1125 const URI: &'static str = "/v2/account/mailcarriers";
1126
1127 pub fn get<C>(client: &C) -> C::Result
1128 where
1129 C: ClientExecutor<Self>,
1130 {
1131 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
1132 }
1133}
1134
1135#[derive(Clone, Debug, Serialize, Deserialize)]
1136pub struct AccountMapChests(Vec<String>);
1137
1138impl AccountMapChests {
1139 const URI: &'static str = "/v2/account/mapchests";
1140
1141 pub fn get<C>(client: &C) -> C::Result
1142 where
1143 C: ClientExecutor<Self>,
1144 {
1145 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
1146 }
1147}
1148
1149/// A list of unlocked masteries.
1150#[derive(Clone, Debug, Serialize, Deserialize)]
1151pub struct AccountMasteries(pub Vec<AccountMastery>);
1152
1153impl AccountMasteries {
1154 const URI: &'static str = "/v2/account/masteries";
1155
1156 pub fn get<C>(client: &C) -> C::Result
1157 where
1158 C: ClientExecutor<Self>,
1159 {
1160 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
1161 }
1162}
1163
1164/// A single unlocked mastery.
1165#[derive(Clone, Debug, Serialize, Deserialize)]
1166pub struct AccountMastery {
1167 /// The id of the mastery track.
1168 pub id: u64,
1169 /// The unlocked level of the mastery track.
1170 pub level: u8,
1171}
1172
1173#[derive(Clone, Debug, Serialize, Deserialize)]
1174pub struct AccountMasteryPoints {
1175 pub totals: Vec<RegionMasteryPoints>,
1176 pub unlocked: Vec<u64>,
1177}
1178
1179impl AccountMasteryPoints {
1180 const URI: &'static str = "/v2/account/mastery/points";
1181
1182 pub fn get<C>(client: &C) -> C::Result
1183 where
1184 C: ClientExecutor<Self>,
1185 {
1186 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
1187 }
1188}
1189
1190#[derive(Clone, Debug, Serialize, Deserialize)]
1191pub struct RegionMasteryPoints {
1192 /// The mastery region.
1193 pub region: String,
1194 /// The number of mastery points spent in mastery tracks.
1195 pub spent: u64,
1196 /// The number of mastery points unlocked.
1197 pub earned: u64,
1198}
1199
1200/// The account's material storage.
1201#[derive(Clone, Debug, Serialize, Deserialize)]
1202pub struct AccountMaterials(Vec<AccountMaterial>);
1203
1204impl AccountMaterials {
1205 const URI: &'static str = "/v2/account/materials";
1206
1207 pub fn get<C>(client: &C) -> C::Result
1208 where
1209 C: ClientExecutor<Self>,
1210 {
1211 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
1212 }
1213}
1214
1215/// A material slot in the account's material storage.
1216#[derive(Clone, Debug, Serialize, Deserialize)]
1217pub struct AccountMaterial {
1218 /// The id of the item.
1219 pub id: u64,
1220 /// The id of the category this item belongs to.
1221 pub category: u8,
1222 /// The binding of the item.
1223 pub binding: Option<ItemBinding>,
1224 /// The number of items of this material stored.
1225 pub count: u16,
1226}
1227
1228#[derive(Clone, Debug, Serialize, Deserialize)]
1229pub struct AccountMinis(pub Vec<u64>);
1230
1231impl AccountMinis {
1232 const URI: &'static str = "/v2/account/minis";
1233
1234 pub fn get<C>(client: &C) -> C::Result
1235 where
1236 C: ClientExecutor<Self>,
1237 {
1238 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
1239 }
1240}
1241
1242/// A list of unlocked mount skins.
1243#[derive(Clone, Debug, Serialize, Deserialize)]
1244pub struct AccountMountSkins(pub Vec<u64>);
1245
1246impl AccountMountSkins {
1247 const URI: &'static str = "/v2/account/mounts/skins";
1248
1249 pub fn get<C>(client: &C) -> C::Result
1250 where
1251 C: ClientExecutor<Self>,
1252 {
1253 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
1254 }
1255}
1256
1257/// A list of unlocked mount types.
1258#[derive(Clone, Debug, Serialize, Deserialize)]
1259pub struct AccountMountTypes(pub Vec<String>);
1260
1261impl AccountMountTypes {
1262 const URI: &'static str = "/v2/account/mounts/types";
1263
1264 pub fn get<C>(client: &C) -> C::Result
1265 where
1266 C: ClientExecutor<Self>,
1267 {
1268 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
1269 }
1270}
1271
1272/// A list of unlocked novelties.
1273#[derive(Clone, Debug, Serialize, Deserialize)]
1274pub struct AccountNovelties(pub Vec<u64>);
1275
1276impl AccountNovelties {
1277 const URI: &'static str = "/v2/account/novelties";
1278
1279 pub fn get<C>(client: &C) -> C::Result
1280 where
1281 C: ClientExecutor<Self>,
1282 {
1283 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
1284 }
1285}
1286
1287/// A list of unlocked outfits.
1288#[derive(Clone, Debug, Serialize, Deserialize)]
1289pub struct AccountOutfits(pub Vec<u64>);
1290
1291impl AccountOutfits {
1292 const URI: &'static str = "/v2/account/outfits";
1293
1294 pub fn get<C>(client: &C) -> C::Result
1295 where
1296 C: ClientExecutor<Self>,
1297 {
1298 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
1299 }
1300}
1301
1302/// A list of account-wide progression.
1303#[derive(Clone, Debug, Serialize, Deserialize)]
1304pub struct AccountProgression(pub Vec<AccountProgressionItem>);
1305
1306impl AccountProgression {
1307 const URI: &'static str = "/v2/account/progression";
1308
1309 pub fn get<C>(client: &C) -> C::Result
1310 where
1311 C: ClientExecutor<Self>,
1312 {
1313 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
1314 }
1315}
1316
1317#[derive(Clone, Debug, Serialize, Deserialize)]
1318pub struct AccountProgressionItem {
1319 /// The name of the progression item.
1320 pub id: String,
1321 /// The value of the progression item.
1322 pub value: u64,
1323}
1324
1325/// A list of unlocked PvP heroes.
1326#[derive(Clone, Debug, Serialize, Deserialize)]
1327pub struct AccountPvPHeroes(pub Vec<u64>);
1328
1329impl AccountPvPHeroes {
1330 const URI: &'static str = "/v2/account/pvp/heroes";
1331
1332 pub fn get<C>(client: &C) -> C::Result
1333 where
1334 C: ClientExecutor<Self>,
1335 {
1336 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
1337 }
1338}
1339
1340/// A list of raid encounters completed since weekly reset.
1341#[derive(Clone, Debug, Serialize, Deserialize)]
1342pub struct AccountRaids(pub Vec<String>);
1343
1344impl AccountRaids {
1345 const URI: &'static str = "/v2/account/raids";
1346
1347 pub fn get<C>(client: &C) -> C::Result
1348 where
1349 C: ClientExecutor<Self>,
1350 {
1351 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
1352 }
1353}
1354
1355/// A list of unlocked recipes.
1356#[derive(Clone, Debug, Serialize, Deserialize)]
1357pub struct AccountRecipes(pub Vec<u64>);
1358
1359impl AccountRecipes {
1360 const URI: &'static str = "/v2/account/recipes";
1361
1362 pub fn get<C>(client: &C) -> C::Result
1363 where
1364 C: ClientExecutor<Self>,
1365 {
1366 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
1367 }
1368}
1369
1370/// A list of unlocked skins.
1371#[derive(Clone, Debug, Serialize, Deserialize)]
1372pub struct AccountSkins(pub Vec<u64>);
1373
1374impl AccountSkins {
1375 const URI: &'static str = "/v2/account/skins";
1376
1377 pub fn get<C>(client: &C) -> C::Result
1378 where
1379 C: ClientExecutor<Self>,
1380 {
1381 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
1382 }
1383}
1384
1385/// A list of unlocked titles.
1386#[derive(Clone, Debug, Serialize, Deserialize)]
1387pub struct AccountTitles(pub Vec<u64>);
1388
1389impl AccountTitles {
1390 const URI: &'static str = "/v2/account/titles";
1391
1392 pub fn get<C>(client: &C) -> C::Result
1393 where
1394 C: ClientExecutor<Self>,
1395 {
1396 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
1397 }
1398}
1399
1400/// A list of currencies in an account's wallet.
1401#[derive(Clone, Debug, Serialize, Deserialize)]
1402pub struct AccountWallet(pub Vec<AccountCurrency>);
1403
1404impl AccountWallet {
1405 const URI: &'static str = "/v2/account/wallet";
1406
1407 pub fn get<C>(client: &C) -> C::Result
1408 where
1409 C: ClientExecutor<Self>,
1410 {
1411 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
1412 }
1413}
1414
1415/// A currency in an account's wallet.
1416#[derive(Clone, Debug, Serialize, Deserialize)]
1417pub struct AccountCurrency {
1418 /// The id of the currency.
1419 pub id: u64,
1420 /// The amount of the currency.
1421 pub value: u64,
1422}
1423
1424/// A list of world bosses completed since daily reset.
1425#[derive(Clone, Debug, Serialize, Deserialize)]
1426pub struct AccountWorldBosses(pub Vec<String>);
1427
1428impl AccountWorldBosses {
1429 const URI: &'static str = "/v2/account/worldbosses";
1430
1431 pub fn get<C>(client: &C) -> C::Result
1432 where
1433 C: ClientExecutor<Self>,
1434 {
1435 client.send(RequestBuilder::new(Self::URI).authenticated(Authentication::Required))
1436 }
1437}