diff options
| -rw-r--r-- | src/gamedata.rs | 68 | ||||
| -rw-r--r-- | src/lib.rs | 26 | 
2 files changed, 88 insertions, 6 deletions
| diff --git a/src/gamedata.rs b/src/gamedata.rs index b7ffc11..b32b385 100644 --- a/src/gamedata.rs +++ b/src/gamedata.rs @@ -126,6 +126,74 @@ impl FromStr for Boss {  /// into account.  pub const XERA_PHASE2_ID: u16 = 0x3F9E; +/// An in-game profession. +/// +/// This only contains the 9 base professions. For elite specializations, see +/// [`EliteSpec`][EliteSpec]. +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, FromPrimitive)] +pub enum Profession { +    Guardian = 1, +    Warrior = 2, +    Engineer = 3, +    Ranger = 4, +    Thief = 5, +    Elementalist = 6, +    Mesmer = 7, +    Necromancer = 8, +    Revenant = 9, +} + +/// All possible elite specializations. +/// +/// Note that the numeric value of the enum variants correspond to the specialization ID in the API +/// as well. See [the official wiki](https://wiki.guildwars2.com/wiki/API:2/specializations) for +/// more information regarding the API usage. +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, FromPrimitive)] +pub enum EliteSpec { +    // Heart of Thorns elites: +    Dragonhunter = 27, +    Berserker = 18, +    Scrapper = 43, +    Druid = 5, +    Daredevil = 7, +    Tempest = 48, +    Chronomancer = 40, +    Reaper = 34, +    Herald = 52, + +    // Path of Fire elites: +    Firebrand = 62, +    Spellbreaker = 61, +    Holosmith = 57, +    Soulbeast = 55, +    Deadeye = 58, +    Weaver = 56, +    Mirage = 59, +    Scourge = 60, +    Renegade = 63, +} + +impl EliteSpec { +    /// Return the profession that this elite specialization belongs to. +    /// +    /// This value is hardcoded (and not expected to change), and does not require a network +    /// connection or API access. +    pub fn profession(self) -> Profession { +        use EliteSpec::*; +        match self { +            Dragonhunter | Firebrand => Profession::Guardian, +            Berserker | Spellbreaker => Profession::Warrior, +            Scrapper | Holosmith => Profession::Engineer, +            Druid | Soulbeast => Profession::Ranger, +            Daredevil | Deadeye => Profession::Thief, +            Tempest | Weaver => Profession::Elementalist, +            Chronomancer | Mirage => Profession::Mesmer, +            Reaper | Scourge => Profession::Necromancer, +            Herald | Renegade => Profession::Revenant, +        } +    } +} +  #[cfg(test)]  mod tests {      use super::*; @@ -20,6 +20,7 @@  use std::marker::PhantomData;  use getset::{CopyGetters, Getters}; +use num_traits::FromPrimitive;  use thiserror::Error;  pub mod raw; @@ -28,12 +29,16 @@ mod event;  pub use event::{Event, EventKind};  pub mod gamedata; -pub use gamedata::Boss; +pub use gamedata::{Boss, EliteSpec, Profession};  #[derive(Error, Debug)]  pub enum EvtcError {      #[error("invalid data has been provided")]      InvalidData, +    #[error("invalid profession id: {0}")] +    InvalidProfession(u32), +    #[error("invalid elite specialization id: {0}")] +    InvalidEliteSpec(u32),      #[error("utf8 decoding error: {0}")]      Utf8Error(#[from] std::string::FromUtf8Error),  } @@ -43,11 +48,11 @@ pub enum EvtcError {  pub struct Player {      /// The player's profession.      #[get_copy = "pub"] -    profession: u32, +    profession: Profession, -    /// The player's elite specialization. +    /// The player's elite specialization, if any is equipped.      #[get_copy = "pub"] -    elite: u32, +    elite: Option<EliteSpec>,      character_name: String, @@ -298,9 +303,18 @@ impl Agent {                  .take_while(|c| *c != 0)                  .collect::<Vec<_>>();              let third = raw_agent.name[first.len() + second.len() + 2] - b'0'; +            let elite = if raw_agent.is_elite == 0 { +                None +            } else { +                Some( +                    EliteSpec::from_u32(raw_agent.is_elite) +                        .ok_or(EvtcError::InvalidEliteSpec(raw_agent.is_elite))?, +                ) +            };              AgentKind::Player(Player { -                profession: raw_agent.prof, -                elite: raw_agent.is_elite, +                profession: Profession::from_u32(raw_agent.prof) +                    .ok_or(EvtcError::InvalidProfession(raw_agent.prof))?, +                elite,                  character_name: String::from_utf8(first)?,                  account_name: String::from_utf8(second)?,                  subgroup: third, | 
