diff options
| author | Daniel Schadt <kingdread@gmx.de> | 2020-05-04 13:33:22 +0200 | 
|---|---|---|
| committer | Daniel Schadt <kingdread@gmx.de> | 2020-05-04 13:33:22 +0200 | 
| commit | 465264c4e087bf37e09d945e49ba2af49c499878 (patch) | |
| tree | 2788f03c7933463bbc4c8c7f66fb81521612dae6 | |
| parent | 78a951211a7afa8ffd1b2fd8ce84a9fb63a23087 (diff) | |
| download | evtclib-465264c4e087bf37e09d945e49ba2af49c499878.tar.gz evtclib-465264c4e087bf37e09d945e49ba2af49c499878.tar.bz2 evtclib-465264c4e087bf37e09d945e49ba2af49c499878.zip | |
implement FromStr for Profession and EliteSpec
For the same reason that Boss implements FromStr, we might want users to
be able to specify professions or elite specializations in textual form.
| -rw-r--r-- | src/gamedata.rs | 175 | 
1 files changed, 174 insertions, 1 deletions
| diff --git a/src/gamedata.rs b/src/gamedata.rs index bfdae10..03942b6 100644 --- a/src/gamedata.rs +++ b/src/gamedata.rs @@ -126,6 +126,11 @@ impl FromStr for Boss {  /// into account.  pub const XERA_PHASE2_ID: u16 = 0x3F9E; +/// Error for when converting a string to a profession fails. +#[derive(Debug, Clone, PartialEq, Eq, Hash, Error)] +#[error("Invalid profession identifier: {0}")] +pub struct ParseProfessionError(String); +  /// An in-game profession.  ///  /// This only contains the 9 base professions. For elite specializations, see @@ -143,6 +148,31 @@ pub enum Profession {      Revenant = 9,  } +impl FromStr for Profession { +    type Err = ParseProfessionError; + +    fn from_str(s: &str) -> Result<Self, Self::Err> { +        match &s.to_lowercase() as &str { +            "guardian" => Ok(Profession::Guardian), +            "warrior" => Ok(Profession::Warrior), +            "engineer" => Ok(Profession::Engineer), +            "ranger" => Ok(Profession::Ranger), +            "thief" => Ok(Profession::Thief), +            "elementalist" => Ok(Profession::Elementalist), +            "mesmer" => Ok(Profession::Mesmer), +            "necromancer" => Ok(Profession::Necromancer), +            "revenant" => Ok(Profession::Revenant), + +            _ => Err(ParseProfessionError(s.to_owned())), +        } +    } +} + +/// Error for when converting a string to an elite specialization fails. +#[derive(Debug, Clone, PartialEq, Eq, Hash, Error)] +#[error("Invalid elite specialization identifier: {0}")] +pub struct ParseEliteSpecError(String); +  /// All possible elite specializations.  ///  /// Note that the numeric value of the enum variants correspond to the specialization ID in the API @@ -173,6 +203,36 @@ pub enum EliteSpec {      Renegade = 63,  } +impl FromStr for EliteSpec { +    type Err = ParseEliteSpecError; + +    fn from_str(s: &str) -> Result<Self, Self::Err> { +        match &s.to_lowercase() as &str { +            "dragonhunter" => Ok(EliteSpec::Dragonhunter), +            "berserker" => Ok(EliteSpec::Berserker), +            "scrapper" => Ok(EliteSpec::Scrapper), +            "druid" => Ok(EliteSpec::Druid), +            "daredevil" => Ok(EliteSpec::Daredevil), +            "tempest" => Ok(EliteSpec::Tempest), +            "chronomancer" => Ok(EliteSpec::Chronomancer), +            "reaper" => Ok(EliteSpec::Reaper), +            "herald" => Ok(EliteSpec::Herald), + +            "firebrand" => Ok(EliteSpec::Firebrand), +            "spellbreaker" => Ok(EliteSpec::Spellbreaker), +            "holosmith" => Ok(EliteSpec::Holosmith), +            "soulbeast" => Ok(EliteSpec::Soulbeast), +            "deadeye" => Ok(EliteSpec::Deadeye), +            "weaver" => Ok(EliteSpec::Weaver), +            "mirage" => Ok(EliteSpec::Mirage), +            "scourge" => Ok(EliteSpec::Scourge), +            "renegade" => Ok(EliteSpec::Renegade), + +            _ => Err(ParseEliteSpecError(s.to_owned())), +        } +    } +} +  impl EliteSpec {      /// Return the profession that this elite specialization belongs to.      /// @@ -281,7 +341,12 @@ mod tests {          ];          for (input, expected) in tests { -            assert_eq!(input.parse(), Ok(*expected)); +            assert_eq!( +                input.parse(), +                Ok(*expected), +                "parsing input {:?} failed", +                input +            );          }      } @@ -303,4 +368,112 @@ mod tests {              assert!(test.parse::<Boss>().is_err());          }      } + +    #[test] +    fn test_profession_parsing_ok() { +        use Profession::*; +        let tests: &[(&'static str, Profession)] = &[ +            ("guardian", Guardian), +            ("Guardian", Guardian), +            ("warrior", Warrior), +            ("Warrior", Warrior), +            ("revenant", Revenant), +            ("Revenant", Revenant), +            ("thief", Thief), +            ("Thief", Thief), +            ("engineer", Engineer), +            ("Engineer", Engineer), +            ("ranger", Ranger), +            ("Ranger", Ranger), +            ("mesmer", Mesmer), +            ("Mesmer", Mesmer), +            ("elementalist", Elementalist), +            ("Elementalist", Elementalist), +            ("necromancer", Necromancer), +            ("Necromancer", Necromancer), +        ]; + +        for (input, expected) in tests { +            assert_eq!( +                input.parse(), +                Ok(*expected), +                "parsing input {:?} failed", +                input +            ); +        } +    } + +    #[test] +    fn test_profession_parsing_err() { +        let tests = &["", "guardiann", "gu", "thiefthief"]; +        for test in tests { +            assert!(test.parse::<Profession>().is_err()); +        } +    } + +    #[test] +    fn test_elite_spec_parsing_ok() { +        use EliteSpec::*; +        let tests: &[(&'static str, EliteSpec)] = &[ +            ("dragonhunter", Dragonhunter), +            ("Dragonhunter", Dragonhunter), +            ("firebrand", Firebrand), +            ("Firebrand", Firebrand), +            ("berserker", Berserker), +            ("Berserker", Berserker), +            ("spellbreaker", Spellbreaker), +            ("Spellbreaker", Spellbreaker), +            ("herald", Herald), +            ("Herald", Herald), +            ("renegade", Renegade), +            ("Renegade", Renegade), +            ("daredevil", Daredevil), +            ("Daredevil", Daredevil), +            ("deadeye", Deadeye), +            ("Deadeye", Deadeye), +            ("scrapper", Scrapper), +            ("Scrapper", Scrapper), +            ("holosmith", Holosmith), +            ("Holosmith", Holosmith), +            ("druid", Druid), +            ("Druid", Druid), +            ("soulbeast", Soulbeast), +            ("Soulbeast", Soulbeast), +            ("tempest", Tempest), +            ("Tempest", Tempest), +            ("weaver", Weaver), +            ("Weaver", Weaver), +            ("chronomancer", Chronomancer), +            ("Chronomancer", Chronomancer), +            ("mirage", Mirage), +            ("Mirage", Mirage), +            ("reaper", Reaper), +            ("Reaper", Reaper), +            ("scourge", Scourge), +            ("Scourge", Scourge), +        ]; + +        for (input, expected) in tests { +            assert_eq!( +                input.parse(), +                Ok(*expected), +                "parsing input {:?} failed", +                input +            ); +        } +    } + +    #[test] +    fn test_elite_spec_parsing_err() { +        let tests = &[ +            "", +            "dragonhunterr", +            "dragonhunt", +            "berserkerberserker", +            "berserk", +        ]; +        for test in tests { +            assert!(test.parse::<EliteSpec>().is_err()); +        } +    }  } | 
