aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Schadt <kingdread@gmx.de>2020-05-04 13:33:22 +0200
committerDaniel Schadt <kingdread@gmx.de>2020-05-04 13:33:22 +0200
commit465264c4e087bf37e09d945e49ba2af49c499878 (patch)
tree2788f03c7933463bbc4c8c7f66fb81521612dae6
parent78a951211a7afa8ffd1b2fd8ce84a9fb63a23087 (diff)
downloadevtclib-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.rs175
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());
+ }
+ }
}