pkstrings: convert STRTOHEX to const fn

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2020-07-06 00:24:06 +02:00
parent 889595a742
commit 8c06d00a19
Signed by: pep
GPG key ID: DEDA74AEECA9D0F2
2 changed files with 98 additions and 95 deletions

View file

@ -6,4 +6,3 @@ edition = "2018"
license = "AGPL-3.0-or-later" license = "AGPL-3.0-or-later"
[dependencies] [dependencies]
lazy_static = "1.4"

View file

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