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 /src | |
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.
Diffstat (limited to 'src')
-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()); + } + } } |