From 6277f0a314c00c6de1b9c75d577fad7b316d6484 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Sat, 10 Jun 2023 14:25:40 +0100
Subject: [PATCH] chore: better add code support

---
 src/genie.rs | 69 ++++++++++++++++++++++++++++++++++------------------
 1 file changed, 46 insertions(+), 23 deletions(-)

diff --git a/src/genie.rs b/src/genie.rs
index 7a2ca2e1..c04f8212 100644
--- a/src/genie.rs
+++ b/src/genie.rs
@@ -31,9 +31,35 @@ impl GameGenie {
         self.codes.get(&addr).unwrap()
     }
 
-    pub fn add_code(&mut self, code: &str) -> Result<&GameGenieCode, &str> {
+    pub fn add_code(&mut self, code: &str) -> Result<&GameGenieCode, String> {
+        let genie_code = match GameGenieCode::from_code(code) {
+            Ok(genie_code) => genie_code,
+            Err(e) => return Err(e),
+        };
+        let addr = genie_code.addr;
+        self.codes.insert(addr, genie_code);
+        Ok(self.get_addr(addr))
+    }
+}
+
+impl Default for GameGenie {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+#[derive(Clone)]
+pub struct GameGenieCode {
+    code: String,
+    addr: u16,
+    new_data: u8,
+    old_data: u8,
+}
+
+impl GameGenieCode {
+    pub fn from_code(code: &str) -> Result<Self, String> {
         if code.len() != 11 {
-            return Err("Invalid Game Genie code length");
+            return Err(String::from("Invalid Game Genie code length"));
         }
 
         let code_u = code.to_uppercase();
@@ -50,33 +76,14 @@ impl GameGenie {
         let addr_slice = format!("{}{}{}", &code_u[6..=6], &code_u[2..=2], &code_u[4..=5]);
         let addr = u16::from_str_radix(addr_slice.as_str(), 16).unwrap() ^ 0xf000;
 
-        let genie_code = GameGenieCode {
+        Ok(Self {
             code: code_u,
             addr,
             new_data,
             old_data,
-        };
-
-        self.codes.insert(addr, genie_code);
-        Ok(self.codes.get(&addr).unwrap())
+        })
     }
-}
-
-impl Default for GameGenie {
-    fn default() -> Self {
-        Self::new()
-    }
-}
-
-#[derive(Clone)]
-pub struct GameGenieCode {
-    code: String,
-    addr: u16,
-    new_data: u8,
-    old_data: u8,
-}
 
-impl GameGenieCode {
     pub fn is_valid(&self, value: u8) -> bool {
         self.old_data == value
     }
@@ -102,3 +109,19 @@ impl Display for GameGenieCode {
         write!(f, "{}", self.short_description())
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use crate::genie::GameGenieCode;
+
+    #[test]
+    fn test_from_code() {
+        let code = "00A-17B-C49";
+        let game_genie_code = GameGenieCode::from_code(code).unwrap();
+
+        assert_eq!(game_genie_code.code, "00A-17B-C49");
+        assert_eq!(game_genie_code.addr, 0x4a17);
+        assert_eq!(game_genie_code.new_data, 0x00);
+        assert_eq!(game_genie_code.old_data, 0xc8);
+    }
+}
-- 
GitLab