Implement FromStr for RelroLevel rather than duplicating the match

Signed-off-by: Johannes Löthberg <[email protected]>
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index a5fa6c8..5661c41 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -790,9 +790,12 @@
 
         fn parse_relro_level(slot: &mut Option<RelroLevel>, v: Option<&str>) -> bool {
             match v {
-                Some("full") => *slot = Some(RelroLevel::Full),
-                Some("partial") => *slot = Some(RelroLevel::Partial),
-                Some("off") => *slot = Some(RelroLevel::Off),
+                Some(s) => {
+                    match s.parse::<RelroLevel>() {
+                        Ok(level) => *slot = Some(level),
+                        _ => return false
+                    }
+                },
                 _ => return false
             }
             true
diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs
index 7ec9b77..55b39f2 100644
--- a/src/librustc_back/lib.rs
+++ b/src/librustc_back/lib.rs
@@ -47,6 +47,8 @@
 pub mod slice;
 pub mod dynamic_lib;
 
+use std::str::FromStr;
+
 use serialize::json::{Json, ToJson};
 
 macro_rules! linker_flavor {
@@ -132,6 +134,19 @@
     }
 }
 
+impl FromStr for RelroLevel {
+    type Err = ();
+
+    fn from_str(s: &str) -> Result<RelroLevel, ()> {
+        match s {
+            "full" => Ok(RelroLevel::Full),
+            "partial" => Ok(RelroLevel::Partial),
+            "off" => Ok(RelroLevel::Off),
+            _ => Err(()),
+        }
+    }
+}
+
 impl ToJson for RelroLevel {
     fn to_json(&self) -> Json {
         match *self {
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index a07f5d1..0dbfdb4 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -588,10 +588,8 @@
             ($key_name:ident, RelroLevel) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
                 obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
-                    match s {
-                        "full" => base.options.$key_name = RelroLevel::Full,
-                        "partial" => base.options.$key_name = RelroLevel::Partial,
-                        "off" => base.options.$key_name = RelroLevel::Off,
+                    match s.parse::<RelroLevel>() {
+                        Ok(level) => base.options.$key_name = level,
                         _ => return Some(Err(format!("'{}' is not a valid value for \
                                                       relro-level. Use 'full', 'partial, or 'off'.",
                                                       s))),