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"
[dependencies]
lazy_static = "1.4"

View file

@ -13,101 +13,105 @@
// 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/>.
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<char, u8> = {
[
('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<u8> {
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<char> {
@ -246,8 +250,8 @@ impl Into<Vec<u8>> 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<String> for PKString {
fn try_from(data: String) -> Result<PKString, Error> {
for chr in data.chars() {
if !STRTOHEX.contains_key(&chr) {
if strtohex(&chr).is_none() {
return Err(Error::InvalidCharacter);
}
}