diff --git a/pkstrings/Cargo.toml b/pkstrings/Cargo.toml index dcbc9a7..41142db 100644 --- a/pkstrings/Cargo.toml +++ b/pkstrings/Cargo.toml @@ -6,4 +6,3 @@ edition = "2018" license = "AGPL-3.0-or-later" [dependencies] -lazy_static = "1.4" diff --git a/pkstrings/src/lib.rs b/pkstrings/src/lib.rs index 4cc196f..2cec5d3 100644 --- a/pkstrings/src/lib.rs +++ b/pkstrings/src/lib.rs @@ -13,101 +13,105 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use lazy_static::lazy_static; -use std::collections::HashMap; use std::convert::TryFrom; use std::fmt; use std::ops::Deref; -lazy_static! { - static ref STRTOHEX: HashMap = { - [ - ('A', 0x80), - ('B', 0x81), - ('C', 0x82), - ('D', 0x83), - ('E', 0x84), - ('F', 0x85), - ('G', 0x86), - ('H', 0x87), - ('I', 0x88), - ('J', 0x89), - ('K', 0x8a), - ('L', 0x8b), - ('M', 0x8c), - ('N', 0x8d), - ('O', 0x8e), - ('P', 0x8f), - ('Q', 0x90), - ('R', 0x91), - ('S', 0x92), - ('T', 0x93), - ('U', 0x94), - ('V', 0x95), - ('W', 0x96), - ('X', 0x97), - ('Y', 0x98), - ('Z', 0x99), - ('(', 0x9a), - (')', 0x9b), - (':', 0x9c), - (';', 0x9d), - ('[', 0x9e), - (']', 0x9f), - ('a', 0xa0), - ('b', 0xa1), - ('c', 0xa2), - ('d', 0xa3), - ('e', 0xa4), - ('f', 0xa5), - ('g', 0xa6), - ('h', 0xa7), - ('i', 0xa8), - ('j', 0xa9), - ('k', 0xaa), - ('l', 0xab), - ('m', 0xac), - ('n', 0xad), - ('o', 0xae), - ('p', 0xaf), - ('q', 0xb0), - ('r', 0xb1), - ('s', 0xb2), - ('t', 0xb3), - ('u', 0xb4), - ('v', 0xb5), - ('w', 0xb6), - ('x', 0xb7), - ('y', 0xb8), - ('z', 0xb9), - ('\'', 0xe0), - ('-', 0xe3), - ('?', 0xe6), - ('!', 0xe7), - ('.', 0xe8), - ('▷', 0xec), - ('▶', 0xed), - ('▼', 0xee), - ('♂', 0xef), - ('×', 0xf1), - ('.', 0xf2), - ('/', 0xf3), - (',', 0xf4), - ('♀', 0xf5), - ('0', 0xf6), - ('1', 0xf7), - ('2', 0xf8), - ('3', 0xf9), - ('4', 0xfa), - ('5', 0xfb), - ('6', 0xfc), - ('7', 0xfd), - ('8', 0xfe), - ('9', 0xff), - (' ', 0x7f), - ('@', 0x50), - ].iter().copied().collect() - }; +const fn strtohex(chr: &char) -> Option { + Some(match chr { + 'A' => 0x80, + 'B' => 0x81, + 'C' => 0x82, + 'D' => 0x83, + 'E' => 0x84, + 'F' => 0x85, + 'G' => 0x86, + 'H' => 0x87, + 'I' => 0x88, + 'J' => 0x89, + 'K' => 0x8a, + 'L' => 0x8b, + 'M' => 0x8c, + 'N' => 0x8d, + 'O' => 0x8e, + 'P' => 0x8f, + 'Q' => 0x90, + 'R' => 0x91, + 'S' => 0x92, + 'T' => 0x93, + 'U' => 0x94, + 'V' => 0x95, + 'W' => 0x96, + 'X' => 0x97, + 'Y' => 0x98, + 'Z' => 0x99, + '(' => 0x9a, + ')' => 0x9b, + ':' => 0x9c, + ';' => 0x9d, + '[' => 0x9e, + ']' => 0x9f, + 'a' => 0xa0, + 'b' => 0xa1, + 'c' => 0xa2, + 'd' => 0xa3, + 'e' => 0xa4, + 'f' => 0xa5, + 'g' => 0xa6, + 'h' => 0xa7, + 'i' => 0xa8, + 'j' => 0xa9, + 'k' => 0xaa, + 'l' => 0xab, + 'm' => 0xac, + 'n' => 0xad, + 'o' => 0xae, + 'p' => 0xaf, + 'q' => 0xb0, + 'r' => 0xb1, + 's' => 0xb2, + 't' => 0xb3, + 'u' => 0xb4, + 'v' => 0xb5, + 'w' => 0xb6, + 'x' => 0xb7, + 'y' => 0xb8, + 'z' => 0xb9, + '\'' => 0xe0, + '-' => 0xe3, + '?' => 0xe6, + '!' => 0xe7, + '.' => 0xe8, + '▷' => 0xec, + '▶' => 0xed, + '▼' => 0xee, + '♂' => 0xef, + '×' => 0xf1, + // TODO: Pattern currently unreachable. Figure something out. + // In the Japanese games (as can be seen below), 0xF2 is distinguishable from 0xE8, with + // the former meant as a decimal point while the latter is punctuation. Presumably this + // intention was largely inherited when the English games were made, as most of the game's + // script uses 0xE8 exclusively; however, 0xF2 appears in the character table for user + // input, meaning it may appear in user-input names (and, conversely, 0xE8 never should). + // Source: https://bulbapedia.bulbagarden.net/wiki/Character_encoding_in_Generation_I + // '.' => 0xf2, + '/' => 0xf3, + ',' => 0xf4, + '♀' => 0xf5, + '0' => 0xf6, + '1' => 0xf7, + '2' => 0xf8, + '3' => 0xf9, + '4' => 0xfa, + '5' => 0xfb, + '6' => 0xfc, + '7' => 0xfd, + '8' => 0xfe, + '9' => 0xff, + ' ' => 0x7f, + '@' => 0x50, + _ => return None, + }) } const fn hextostr(hex: u8) -> Option { @@ -246,8 +250,8 @@ impl Into> for PKString { let mut vec = Vec::with_capacity(self.len()); for chr in self.0.chars() { - if let Some(ord) = STRTOHEX.get(&chr) { - vec.push(*ord); + if let Some(ord) = strtohex(&chr) { + vec.push(ord); } else { // TODO: Change this. panic!(); @@ -271,7 +275,7 @@ impl TryFrom for PKString { fn try_from(data: String) -> Result { for chr in data.chars() { - if !STRTOHEX.contains_key(&chr) { + if strtohex(&chr).is_none() { return Err(Error::InvalidCharacter); } }