Fix parsing of Champion, improve error handling

pull/37/head
Mingwei Samuel 2021-12-29 11:50:45 -08:00
parent 2f4d1dc65c
commit d05f89c0d4
4 changed files with 215 additions and 189 deletions

View File

@ -860,182 +860,195 @@ impl Champion {
} }
} }
#[derive(Debug)]
pub struct ParseChampionError([char; 4]);
impl std::fmt::Display for ParseChampionError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let s: String = self.0.iter().copied().take_while(|&c| '\0' != c).collect();
write!(f, "Failed to parse unknown champion prefix: {:?}", s)
}
}
impl std::error::Error for ParseChampionError {}
impl std::str::FromStr for Champion { impl std::str::FromStr for Champion {
type Err = (); type Err = ParseChampionError;
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.chars() let mut chars = ['\0'; 4];
s.chars()
.take(4) .take(4)
.filter(|c| c.is_ascii_alphanumeric()) .filter(|c| c.is_ascii_alphanumeric())
.fold(0_u32, |hash, next| hash * 256 + u32::from(next)) .map(|c| c.to_ascii_uppercase())
{ .enumerate()
0x41415452 /* AATR */ => Ok(Champion::AATROX), .for_each(|(i, c)| chars[i] = c);
0x41485249 /* AHRI */ => Ok(Champion::AHRI), match chars {
0x414b414c /* AKAL */ => Ok(Champion::AKALI), /* AATR */ [ 'A', 'A', 'T', 'R'] => Ok(Champion::AATROX),
0x414b5348 /* AKSH */ => Ok(Champion::AKSHAN), /* AHRI */ [ 'A', 'H', 'R', 'I'] => Ok(Champion::AHRI),
0x414c4953 /* ALIS */ => Ok(Champion::ALISTAR), /* AKAL */ [ 'A', 'K', 'A', 'L'] => Ok(Champion::AKALI),
0x414d554d /* AMUM */ => Ok(Champion::AMUMU), /* AKSH */ [ 'A', 'K', 'S', 'H'] => Ok(Champion::AKSHAN),
0x414e4956 /* ANIV */ => Ok(Champion::ANIVIA), /* ALIS */ [ 'A', 'L', 'I', 'S'] => Ok(Champion::ALISTAR),
0x414e4e49 /* ANNI */ => Ok(Champion::ANNIE), /* AMUM */ [ 'A', 'M', 'U', 'M'] => Ok(Champion::AMUMU),
0x41504845 /* APHE */ => Ok(Champion::APHELIOS), /* ANIV */ [ 'A', 'N', 'I', 'V'] => Ok(Champion::ANIVIA),
0x41534845 /* ASHE */ => Ok(Champion::ASHE), /* ANNI */ [ 'A', 'N', 'N', 'I'] => Ok(Champion::ANNIE),
0x41555245 /* AURE */ => Ok(Champion::AURELION_SOL), /* APHE */ [ 'A', 'P', 'H', 'E'] => Ok(Champion::APHELIOS),
0x415a4952 /* AZIR */ => Ok(Champion::AZIR), /* ASHE */ [ 'A', 'S', 'H', 'E'] => Ok(Champion::ASHE),
0x42415244 /* BARD */ => Ok(Champion::BARD), /* AURE */ [ 'A', 'U', 'R', 'E'] => Ok(Champion::AURELION_SOL),
0x424c4954 /* BLIT */ => Ok(Champion::BLITZCRANK), /* AZIR */ [ 'A', 'Z', 'I', 'R'] => Ok(Champion::AZIR),
0x4252414e /* BRAN */ => Ok(Champion::BRAND), /* BARD */ [ 'B', 'A', 'R', 'D'] => Ok(Champion::BARD),
0x42524155 /* BRAU */ => Ok(Champion::BRAUM), /* BLIT */ [ 'B', 'L', 'I', 'T'] => Ok(Champion::BLITZCRANK),
0x43414954 /* CAIT */ => Ok(Champion::CAITLYN), /* BRAN */ [ 'B', 'R', 'A', 'N'] => Ok(Champion::BRAND),
0x43414d49 /* CAMI */ => Ok(Champion::CAMILLE), /* BRAU */ [ 'B', 'R', 'A', 'U'] => Ok(Champion::BRAUM),
0x43415353 /* CASS */ => Ok(Champion::CASSIOPEIA), /* CAIT */ [ 'C', 'A', 'I', 'T'] => Ok(Champion::CAITLYN),
0x43484f47 /* CHOG */ => Ok(Champion::CHO_GATH), /* CAMI */ [ 'C', 'A', 'M', 'I'] => Ok(Champion::CAMILLE),
0x43484f /* CHO */ => Ok(Champion::CHO_GATH), /* CASS */ [ 'C', 'A', 'S', 'S'] => Ok(Champion::CASSIOPEIA),
0x434f524b /* CORK */ => Ok(Champion::CORKI), /* CHOG */ [ 'C', 'H', 'O', 'G'] => Ok(Champion::CHO_GATH),
0x44415249 /* DARI */ => Ok(Champion::DARIUS), /* CHO */ [ 'C', 'H', 'O', '\0'] => Ok(Champion::CHO_GATH),
0x4449414e /* DIAN */ => Ok(Champion::DIANA), /* CORK */ [ 'C', 'O', 'R', 'K'] => Ok(Champion::CORKI),
0x44524d55 /* DRMU */ => Ok(Champion::DR_MUNDO), /* DARI */ [ 'D', 'A', 'R', 'I'] => Ok(Champion::DARIUS),
0x4452 /* DR */ => Ok(Champion::DR_MUNDO), /* DIAN */ [ 'D', 'I', 'A', 'N'] => Ok(Champion::DIANA),
0x44524156 /* DRAV */ => Ok(Champion::DRAVEN), /* DRMU */ [ 'D', 'R', 'M', 'U'] => Ok(Champion::DR_MUNDO),
0x454b4b4f /* EKKO */ => Ok(Champion::EKKO), /* DR */ [ 'D', 'R', '\0', '\0'] => Ok(Champion::DR_MUNDO),
0x454c4953 /* ELIS */ => Ok(Champion::ELISE), /* DRAV */ [ 'D', 'R', 'A', 'V'] => Ok(Champion::DRAVEN),
0x4556454c /* EVEL */ => Ok(Champion::EVELYNN), /* EKKO */ [ 'E', 'K', 'K', 'O'] => Ok(Champion::EKKO),
0x455a5245 /* EZRE */ => Ok(Champion::EZREAL), /* ELIS */ [ 'E', 'L', 'I', 'S'] => Ok(Champion::ELISE),
0x46494444 /* FIDD */ => Ok(Champion::FIDDLESTICKS), /* EVEL */ [ 'E', 'V', 'E', 'L'] => Ok(Champion::EVELYNN),
0x46494f52 /* FIOR */ => Ok(Champion::FIORA), /* EZRE */ [ 'E', 'Z', 'R', 'E'] => Ok(Champion::EZREAL),
0x46495a5a /* FIZZ */ => Ok(Champion::FIZZ), /* FIDD */ [ 'F', 'I', 'D', 'D'] => Ok(Champion::FIDDLESTICKS),
0x47414c49 /* GALI */ => Ok(Champion::GALIO), /* FIOR */ [ 'F', 'I', 'O', 'R'] => Ok(Champion::FIORA),
0x47414e47 /* GANG */ => Ok(Champion::GANGPLANK), /* FIZZ */ [ 'F', 'I', 'Z', 'Z'] => Ok(Champion::FIZZ),
0x47415245 /* GARE */ => Ok(Champion::GAREN), /* GALI */ [ 'G', 'A', 'L', 'I'] => Ok(Champion::GALIO),
0x474e4152 /* GNAR */ => Ok(Champion::GNAR), /* GANG */ [ 'G', 'A', 'N', 'G'] => Ok(Champion::GANGPLANK),
0x47524147 /* GRAG */ => Ok(Champion::GRAGAS), /* GARE */ [ 'G', 'A', 'R', 'E'] => Ok(Champion::GAREN),
0x47524156 /* GRAV */ => Ok(Champion::GRAVES), /* GNAR */ [ 'G', 'N', 'A', 'R'] => Ok(Champion::GNAR),
0x4757454e /* GWEN */ => Ok(Champion::GWEN), /* GRAG */ [ 'G', 'R', 'A', 'G'] => Ok(Champion::GRAGAS),
0x48454341 /* HECA */ => Ok(Champion::HECARIM), /* GRAV */ [ 'G', 'R', 'A', 'V'] => Ok(Champion::GRAVES),
0x4845494d /* HEIM */ => Ok(Champion::HEIMERDINGER), /* GWEN */ [ 'G', 'W', 'E', 'N'] => Ok(Champion::GWEN),
0x494c4c41 /* ILLA */ => Ok(Champion::ILLAOI), /* HECA */ [ 'H', 'E', 'C', 'A'] => Ok(Champion::HECARIM),
0x4952454c /* IREL */ => Ok(Champion::IRELIA), /* HEIM */ [ 'H', 'E', 'I', 'M'] => Ok(Champion::HEIMERDINGER),
0x49564552 /* IVER */ => Ok(Champion::IVERN), /* ILLA */ [ 'I', 'L', 'L', 'A'] => Ok(Champion::ILLAOI),
0x4a414e4e /* JANN */ => Ok(Champion::JANNA), /* IREL */ [ 'I', 'R', 'E', 'L'] => Ok(Champion::IRELIA),
0x4a415256 /* JARV */ => Ok(Champion::JARVAN_IV), /* IVER */ [ 'I', 'V', 'E', 'R'] => Ok(Champion::IVERN),
0x4a4158 /* JAX */ => Ok(Champion::JAX), /* JANN */ [ 'J', 'A', 'N', 'N'] => Ok(Champion::JANNA),
0x4a415943 /* JAYC */ => Ok(Champion::JAYCE), /* JARV */ [ 'J', 'A', 'R', 'V'] => Ok(Champion::JARVAN_IV),
0x4a48494e /* JHIN */ => Ok(Champion::JHIN), /* JAX */ [ 'J', 'A', 'X', '\0'] => Ok(Champion::JAX),
0x4a494e58 /* JINX */ => Ok(Champion::JINX), /* JAYC */ [ 'J', 'A', 'Y', 'C'] => Ok(Champion::JAYCE),
0x4b414953 /* KAIS */ => Ok(Champion::KAI_SA), /* JHIN */ [ 'J', 'H', 'I', 'N'] => Ok(Champion::JHIN),
0x4b4149 /* KAI */ => Ok(Champion::KAI_SA), /* JINX */ [ 'J', 'I', 'N', 'X'] => Ok(Champion::JINX),
0x4b414c49 /* KALI */ => Ok(Champion::KALISTA), /* KAIS */ [ 'K', 'A', 'I', 'S'] => Ok(Champion::KAI_SA),
0x4b41524d /* KARM */ => Ok(Champion::KARMA), /* KAI */ [ 'K', 'A', 'I', '\0'] => Ok(Champion::KAI_SA),
0x4b415254 /* KART */ => Ok(Champion::KARTHUS), /* KALI */ [ 'K', 'A', 'L', 'I'] => Ok(Champion::KALISTA),
0x4b415353 /* KASS */ => Ok(Champion::KASSADIN), /* KARM */ [ 'K', 'A', 'R', 'M'] => Ok(Champion::KARMA),
0x4b415441 /* KATA */ => Ok(Champion::KATARINA), /* KART */ [ 'K', 'A', 'R', 'T'] => Ok(Champion::KARTHUS),
0x4b41594c /* KAYL */ => Ok(Champion::KAYLE), /* KASS */ [ 'K', 'A', 'S', 'S'] => Ok(Champion::KASSADIN),
0x4b41594e /* KAYN */ => Ok(Champion::KAYN), /* KATA */ [ 'K', 'A', 'T', 'A'] => Ok(Champion::KATARINA),
0x4b454e4e /* KENN */ => Ok(Champion::KENNEN), /* KAYL */ [ 'K', 'A', 'Y', 'L'] => Ok(Champion::KAYLE),
0x4b48415a /* KHAZ */ => Ok(Champion::KHA_ZIX), /* KAYN */ [ 'K', 'A', 'Y', 'N'] => Ok(Champion::KAYN),
0x4b4841 /* KHA */ => Ok(Champion::KHA_ZIX), /* KENN */ [ 'K', 'E', 'N', 'N'] => Ok(Champion::KENNEN),
0x4b494e44 /* KIND */ => Ok(Champion::KINDRED), /* KHAZ */ [ 'K', 'H', 'A', 'Z'] => Ok(Champion::KHA_ZIX),
0x4b4c4544 /* KLED */ => Ok(Champion::KLED), /* KHA */ [ 'K', 'H', 'A', '\0'] => Ok(Champion::KHA_ZIX),
0x4b4f474d /* KOGM */ => Ok(Champion::KOG_MAW), /* KIND */ [ 'K', 'I', 'N', 'D'] => Ok(Champion::KINDRED),
0x4b4f47 /* KOG */ => Ok(Champion::KOG_MAW), /* KLED */ [ 'K', 'L', 'E', 'D'] => Ok(Champion::KLED),
0x4c45424c /* LEBL */ => Ok(Champion::LE_BLANC), /* KOGM */ [ 'K', 'O', 'G', 'M'] => Ok(Champion::KOG_MAW),
0x4c454553 /* LEES */ => Ok(Champion::LEE_SIN), /* KOG */ [ 'K', 'O', 'G', '\0'] => Ok(Champion::KOG_MAW),
0x4c4545 /* LEE */ => Ok(Champion::LEE_SIN), /* LEBL */ [ 'L', 'E', 'B', 'L'] => Ok(Champion::LE_BLANC),
0x4c454f4e /* LEON */ => Ok(Champion::LEONA), /* LEES */ [ 'L', 'E', 'E', 'S'] => Ok(Champion::LEE_SIN),
0x4c494c4c /* LILL */ => Ok(Champion::LILLIA), /* LEE */ [ 'L', 'E', 'E', '\0'] => Ok(Champion::LEE_SIN),
0x4c495353 /* LISS */ => Ok(Champion::LISSANDRA), /* LEON */ [ 'L', 'E', 'O', 'N'] => Ok(Champion::LEONA),
0x4c554349 /* LUCI */ => Ok(Champion::LUCIAN), /* LILL */ [ 'L', 'I', 'L', 'L'] => Ok(Champion::LILLIA),
0x4c554c55 /* LULU */ => Ok(Champion::LULU), /* LISS */ [ 'L', 'I', 'S', 'S'] => Ok(Champion::LISSANDRA),
0x4c5558 /* LUX */ => Ok(Champion::LUX), /* LUCI */ [ 'L', 'U', 'C', 'I'] => Ok(Champion::LUCIAN),
0x4d414c50 /* MALP */ => Ok(Champion::MALPHITE), /* LULU */ [ 'L', 'U', 'L', 'U'] => Ok(Champion::LULU),
0x4d414c5a /* MALZ */ => Ok(Champion::MALZAHAR), /* LUX */ [ 'L', 'U', 'X', '\0'] => Ok(Champion::LUX),
0x4d414f4b /* MAOK */ => Ok(Champion::MAOKAI), /* MALP */ [ 'M', 'A', 'L', 'P'] => Ok(Champion::MALPHITE),
0x4d415354 /* MAST */ => Ok(Champion::MASTER_YI), /* MALZ */ [ 'M', 'A', 'L', 'Z'] => Ok(Champion::MALZAHAR),
0x4d495353 /* MISS */ => Ok(Champion::MISS_FORTUNE), /* MAOK */ [ 'M', 'A', 'O', 'K'] => Ok(Champion::MAOKAI),
0x4d4f5244 /* MORD */ => Ok(Champion::MORDEKAISER), /* MAST */ [ 'M', 'A', 'S', 'T'] => Ok(Champion::MASTER_YI),
0x4d4f5247 /* MORG */ => Ok(Champion::MORGANA), /* MISS */ [ 'M', 'I', 'S', 'S'] => Ok(Champion::MISS_FORTUNE),
0x4e414d49 /* NAMI */ => Ok(Champion::NAMI), /* MORD */ [ 'M', 'O', 'R', 'D'] => Ok(Champion::MORDEKAISER),
0x4e415355 /* NASU */ => Ok(Champion::NASUS), /* MORG */ [ 'M', 'O', 'R', 'G'] => Ok(Champion::MORGANA),
0x4e415554 /* NAUT */ => Ok(Champion::NAUTILUS), /* NAMI */ [ 'N', 'A', 'M', 'I'] => Ok(Champion::NAMI),
0x4e45454b /* NEEK */ => Ok(Champion::NEEKO), /* NASU */ [ 'N', 'A', 'S', 'U'] => Ok(Champion::NASUS),
0x4e494441 /* NIDA */ => Ok(Champion::NIDALEE), /* NAUT */ [ 'N', 'A', 'U', 'T'] => Ok(Champion::NAUTILUS),
0x4e4f4354 /* NOCT */ => Ok(Champion::NOCTURNE), /* NEEK */ [ 'N', 'E', 'E', 'K'] => Ok(Champion::NEEKO),
0x4e554e55 /* NUNU */ => Ok(Champion::NUNU_WILLUMP), /* NIDA */ [ 'N', 'I', 'D', 'A'] => Ok(Champion::NIDALEE),
0x4f4c4146 /* OLAF */ => Ok(Champion::OLAF), /* NOCT */ [ 'N', 'O', 'C', 'T'] => Ok(Champion::NOCTURNE),
0x4f524941 /* ORIA */ => Ok(Champion::ORIANNA), /* NUNU */ [ 'N', 'U', 'N', 'U'] => Ok(Champion::NUNU_WILLUMP),
0x4f524e4e /* ORNN */ => Ok(Champion::ORNN), /* OLAF */ [ 'O', 'L', 'A', 'F'] => Ok(Champion::OLAF),
0x50414e54 /* PANT */ => Ok(Champion::PANTHEON), /* ORIA */ [ 'O', 'R', 'I', 'A'] => Ok(Champion::ORIANNA),
0x504f5050 /* POPP */ => Ok(Champion::POPPY), /* ORNN */ [ 'O', 'R', 'N', 'N'] => Ok(Champion::ORNN),
0x50594b45 /* PYKE */ => Ok(Champion::PYKE), /* PANT */ [ 'P', 'A', 'N', 'T'] => Ok(Champion::PANTHEON),
0x51495941 /* QIYA */ => Ok(Champion::QIYANA), /* POPP */ [ 'P', 'O', 'P', 'P'] => Ok(Champion::POPPY),
0x5155494e /* QUIN */ => Ok(Champion::QUINN), /* PYKE */ [ 'P', 'Y', 'K', 'E'] => Ok(Champion::PYKE),
0x52414b41 /* RAKA */ => Ok(Champion::RAKAN), /* QIYA */ [ 'Q', 'I', 'Y', 'A'] => Ok(Champion::QIYANA),
0x52414d4d /* RAMM */ => Ok(Champion::RAMMUS), /* QUIN */ [ 'Q', 'U', 'I', 'N'] => Ok(Champion::QUINN),
0x52454b53 /* REKS */ => Ok(Champion::REK_SAI), /* RAKA */ [ 'R', 'A', 'K', 'A'] => Ok(Champion::RAKAN),
0x52454b /* REK */ => Ok(Champion::REK_SAI), /* RAMM */ [ 'R', 'A', 'M', 'M'] => Ok(Champion::RAMMUS),
0x52454c4c /* RELL */ => Ok(Champion::RELL), /* REKS */ [ 'R', 'E', 'K', 'S'] => Ok(Champion::REK_SAI),
0x52454e45 /* RENE */ => Ok(Champion::RENEKTON), /* REK */ [ 'R', 'E', 'K', '\0'] => Ok(Champion::REK_SAI),
0x52454e47 /* RENG */ => Ok(Champion::RENGAR), /* RELL */ [ 'R', 'E', 'L', 'L'] => Ok(Champion::RELL),
0x52495645 /* RIVE */ => Ok(Champion::RIVEN), /* RENE */ [ 'R', 'E', 'N', 'E'] => Ok(Champion::RENEKTON),
0x52554d42 /* RUMB */ => Ok(Champion::RUMBLE), /* RENG */ [ 'R', 'E', 'N', 'G'] => Ok(Champion::RENGAR),
0x52595a45 /* RYZE */ => Ok(Champion::RYZE), /* RIVE */ [ 'R', 'I', 'V', 'E'] => Ok(Champion::RIVEN),
0x53414d49 /* SAMI */ => Ok(Champion::SAMIRA), /* RUMB */ [ 'R', 'U', 'M', 'B'] => Ok(Champion::RUMBLE),
0x53454a55 /* SEJU */ => Ok(Champion::SEJUANI), /* RYZE */ [ 'R', 'Y', 'Z', 'E'] => Ok(Champion::RYZE),
0x53454e4e /* SENN */ => Ok(Champion::SENNA), /* SAMI */ [ 'S', 'A', 'M', 'I'] => Ok(Champion::SAMIRA),
0x53455241 /* SERA */ => Ok(Champion::SERAPHINE), /* SEJU */ [ 'S', 'E', 'J', 'U'] => Ok(Champion::SEJUANI),
0x53455454 /* SETT */ => Ok(Champion::SETT), /* SENN */ [ 'S', 'E', 'N', 'N'] => Ok(Champion::SENNA),
0x53484143 /* SHAC */ => Ok(Champion::SHACO), /* SERA */ [ 'S', 'E', 'R', 'A'] => Ok(Champion::SERAPHINE),
0x5348454e /* SHEN */ => Ok(Champion::SHEN), /* SETT */ [ 'S', 'E', 'T', 'T'] => Ok(Champion::SETT),
0x53485956 /* SHYV */ => Ok(Champion::SHYVANA), /* SHAC */ [ 'S', 'H', 'A', 'C'] => Ok(Champion::SHACO),
0x53494e47 /* SING */ => Ok(Champion::SINGED), /* SHEN */ [ 'S', 'H', 'E', 'N'] => Ok(Champion::SHEN),
0x53494f4e /* SION */ => Ok(Champion::SION), /* SHYV */ [ 'S', 'H', 'Y', 'V'] => Ok(Champion::SHYVANA),
0x53495649 /* SIVI */ => Ok(Champion::SIVIR), /* SING */ [ 'S', 'I', 'N', 'G'] => Ok(Champion::SINGED),
0x534b4152 /* SKAR */ => Ok(Champion::SKARNER), /* SION */ [ 'S', 'I', 'O', 'N'] => Ok(Champion::SION),
0x534f4e41 /* SONA */ => Ok(Champion::SONA), /* SIVI */ [ 'S', 'I', 'V', 'I'] => Ok(Champion::SIVIR),
0x534f5241 /* SORA */ => Ok(Champion::SORAKA), /* SKAR */ [ 'S', 'K', 'A', 'R'] => Ok(Champion::SKARNER),
0x53574149 /* SWAI */ => Ok(Champion::SWAIN), /* SONA */ [ 'S', 'O', 'N', 'A'] => Ok(Champion::SONA),
0x53594c41 /* SYLA */ => Ok(Champion::SYLAS), /* SORA */ [ 'S', 'O', 'R', 'A'] => Ok(Champion::SORAKA),
0x53594e44 /* SYND */ => Ok(Champion::SYNDRA), /* SWAI */ [ 'S', 'W', 'A', 'I'] => Ok(Champion::SWAIN),
0x5441484d /* TAHM */ => Ok(Champion::TAHM_KENCH), /* SYLA */ [ 'S', 'Y', 'L', 'A'] => Ok(Champion::SYLAS),
0x54414c49 /* TALI */ => Ok(Champion::TALIYAH), /* SYND */ [ 'S', 'Y', 'N', 'D'] => Ok(Champion::SYNDRA),
0x54414c4f /* TALO */ => Ok(Champion::TALON), /* TAHM */ [ 'T', 'A', 'H', 'M'] => Ok(Champion::TAHM_KENCH),
0x54415249 /* TARI */ => Ok(Champion::TARIC), /* TALI */ [ 'T', 'A', 'L', 'I'] => Ok(Champion::TALIYAH),
0x5445454d /* TEEM */ => Ok(Champion::TEEMO), /* TALO */ [ 'T', 'A', 'L', 'O'] => Ok(Champion::TALON),
0x54485245 /* THRE */ => Ok(Champion::THRESH), /* TARI */ [ 'T', 'A', 'R', 'I'] => Ok(Champion::TARIC),
0x54524953 /* TRIS */ => Ok(Champion::TRISTANA), /* TEEM */ [ 'T', 'E', 'E', 'M'] => Ok(Champion::TEEMO),
0x5452554e /* TRUN */ => Ok(Champion::TRUNDLE), /* THRE */ [ 'T', 'H', 'R', 'E'] => Ok(Champion::THRESH),
0x5452594e /* TRYN */ => Ok(Champion::TRYNDAMERE), /* TRIS */ [ 'T', 'R', 'I', 'S'] => Ok(Champion::TRISTANA),
0x54574953 /* TWIS */ => Ok(Champion::TWISTED_FATE), /* TRUN */ [ 'T', 'R', 'U', 'N'] => Ok(Champion::TRUNDLE),
0x54574954 /* TWIT */ => Ok(Champion::TWITCH), /* TRYN */ [ 'T', 'R', 'Y', 'N'] => Ok(Champion::TRYNDAMERE),
0x55445952 /* UDYR */ => Ok(Champion::UDYR), /* TWIS */ [ 'T', 'W', 'I', 'S'] => Ok(Champion::TWISTED_FATE),
0x5552474f /* URGO */ => Ok(Champion::URGOT), /* TWIT */ [ 'T', 'W', 'I', 'T'] => Ok(Champion::TWITCH),
0x56415255 /* VARU */ => Ok(Champion::VARUS), /* UDYR */ [ 'U', 'D', 'Y', 'R'] => Ok(Champion::UDYR),
0x5641594e /* VAYN */ => Ok(Champion::VAYNE), /* URGO */ [ 'U', 'R', 'G', 'O'] => Ok(Champion::URGOT),
0x56454947 /* VEIG */ => Ok(Champion::VEIGAR), /* VARU */ [ 'V', 'A', 'R', 'U'] => Ok(Champion::VARUS),
0x56454c4b /* VELK */ => Ok(Champion::VEL_KOZ), /* VAYN */ [ 'V', 'A', 'Y', 'N'] => Ok(Champion::VAYNE),
0x56454c /* VEL */ => Ok(Champion::VEL_KOZ), /* VEIG */ [ 'V', 'E', 'I', 'G'] => Ok(Champion::VEIGAR),
0x564558 /* VEX */ => Ok(Champion::VEX), /* VELK */ [ 'V', 'E', 'L', 'K'] => Ok(Champion::VEL_KOZ),
0x5649 /* VI */ => Ok(Champion::VI), /* VEL */ [ 'V', 'E', 'L', '\0'] => Ok(Champion::VEL_KOZ),
0x56494547 /* VIEG */ => Ok(Champion::VIEGO), /* VEX */ [ 'V', 'E', 'X', '\0'] => Ok(Champion::VEX),
0x56494b54 /* VIKT */ => Ok(Champion::VIKTOR), /* VI */ [ 'V', 'I', '\0', '\0'] => Ok(Champion::VI),
0x564c4144 /* VLAD */ => Ok(Champion::VLADIMIR), /* VIEG */ [ 'V', 'I', 'E', 'G'] => Ok(Champion::VIEGO),
0x564f4c49 /* VOLI */ => Ok(Champion::VOLIBEAR), /* VIKT */ [ 'V', 'I', 'K', 'T'] => Ok(Champion::VIKTOR),
0x57415257 /* WARW */ => Ok(Champion::WARWICK), /* VLAD */ [ 'V', 'L', 'A', 'D'] => Ok(Champion::VLADIMIR),
0x57554b4f /* WUKO */ => Ok(Champion::WUKONG), /* VOLI */ [ 'V', 'O', 'L', 'I'] => Ok(Champion::VOLIBEAR),
0x4d4f4e4b /* MONK */ => Ok(Champion::WUKONG), /* WARW */ [ 'W', 'A', 'R', 'W'] => Ok(Champion::WARWICK),
0x58415941 /* XAYA */ => Ok(Champion::XAYAH), /* WUKO */ [ 'W', 'U', 'K', 'O'] => Ok(Champion::WUKONG),
0x58455241 /* XERA */ => Ok(Champion::XERATH), /* MONK */ [ 'M', 'O', 'N', 'K'] => Ok(Champion::WUKONG),
0x58494e5a /* XINZ */ => Ok(Champion::XIN_ZHAO), /* XAYA */ [ 'X', 'A', 'Y', 'A'] => Ok(Champion::XAYAH),
0x58494e /* XIN */ => Ok(Champion::XIN_ZHAO), /* XERA */ [ 'X', 'E', 'R', 'A'] => Ok(Champion::XERATH),
0x59415355 /* YASU */ => Ok(Champion::YASUO), /* XINZ */ [ 'X', 'I', 'N', 'Z'] => Ok(Champion::XIN_ZHAO),
0x594f4e45 /* YONE */ => Ok(Champion::YONE), /* XIN */ [ 'X', 'I', 'N', '\0'] => Ok(Champion::XIN_ZHAO),
0x594f5249 /* YORI */ => Ok(Champion::YORICK), /* YASU */ [ 'Y', 'A', 'S', 'U'] => Ok(Champion::YASUO),
0x5955554d /* YUUM */ => Ok(Champion::YUUMI), /* YONE */ [ 'Y', 'O', 'N', 'E'] => Ok(Champion::YONE),
0x5a4143 /* ZAC */ => Ok(Champion::ZAC), /* YORI */ [ 'Y', 'O', 'R', 'I'] => Ok(Champion::YORICK),
0x5a4544 /* ZED */ => Ok(Champion::ZED), /* YUUM */ [ 'Y', 'U', 'U', 'M'] => Ok(Champion::YUUMI),
0x5a494747 /* ZIGG */ => Ok(Champion::ZIGGS), /* ZAC */ [ 'Z', 'A', 'C', '\0'] => Ok(Champion::ZAC),
0x5a494c45 /* ZILE */ => Ok(Champion::ZILEAN), /* ZED */ [ 'Z', 'E', 'D', '\0'] => Ok(Champion::ZED),
0x5a4f45 /* ZOE */ => Ok(Champion::ZOE), /* ZIGG */ [ 'Z', 'I', 'G', 'G'] => Ok(Champion::ZIGGS),
0x5a595241 /* ZYRA */ => Ok(Champion::ZYRA), /* ZILE */ [ 'Z', 'I', 'L', 'E'] => Ok(Champion::ZILEAN),
_ => Err(()), /* ZOE */ [ 'Z', 'O', 'E', '\0'] => Ok(Champion::ZOE),
/* ZYRA */ [ 'Z', 'Y', 'R', 'A'] => Ok(Champion::ZYRA),
unknown => Err(ParseChampionError(unknown)),
} }
} }
} }

View File

@ -1,4 +1,3 @@
use std::error::Error as StdError;
use std::fmt; use std::fmt;
use reqwest::{ Error, Response, StatusCode }; use reqwest::{ Error, Response, StatusCode };
@ -58,8 +57,8 @@ impl fmt::Display for RiotApiError {
write!(f, "{:#?}", self) write!(f, "{:#?}", self)
} }
} }
impl StdError for RiotApiError { impl std::error::Error for RiotApiError {
fn source(&self) -> Option<&(dyn StdError + 'static)> { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.reqwest_error) Some(&self.reqwest_error)
} }
} }

View File

@ -6,14 +6,6 @@
const constName = name => dotUtils.changeCase.constantCase(name).replace(/[^_A-Z0-9]+/g, ''); const constName = name => dotUtils.changeCase.constantCase(name).replace(/[^_A-Z0-9]+/g, '');
const constNamePad = 12; const constNamePad = 12;
const hashFactor = 256;
const strHash = (str) => {
let h = 0;
for (const c of str)
h = hashFactor * h + c.charCodeAt(0);
return h;
};
}}{{= dotUtils.preamble() }} }}{{= dotUtils.preamble() }}
newtype_enum! { newtype_enum! {
@ -115,14 +107,27 @@ impl Champion {
} }
} }
#[derive(Debug)]
pub struct ParseChampionError([char; 4]);
impl std::fmt::Display for ParseChampionError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let s: String = self.0.iter().copied().take_while(|&c| '\0' != c).collect();
write!(f, "Failed to parse unknown champion prefix: {:?}", s)
}
}
impl std::error::Error for ParseChampionError {}
impl std::str::FromStr for Champion { impl std::str::FromStr for Champion {
type Err = (); type Err = ParseChampionError;
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.chars() let mut chars = ['\0'; 4];
s.chars()
.take(4) .take(4)
.filter(|c| c.is_ascii_alphanumeric()) .filter(|c| c.is_ascii_alphanumeric())
.fold(0_u32, |hash, next| hash * {{= hashFactor }} + u32::from(next)) .map(|c| c.to_ascii_uppercase())
{ .enumerate()
.for_each(|(i, c)| chars[i] = c);
match chars {
{{ {{
const keyStrings = (name, alias) => new Set([].concat(...[ name, alias ].map(s => s.toUpperCase()) const keyStrings = (name, alias) => new Set([].concat(...[ name, alias ].map(s => s.toUpperCase())
.map(s => [ .map(s => [
@ -132,13 +137,16 @@ impl std::str::FromStr for Champion {
]))); ])));
for (const { id, alias, name } of champions) { for (const { id, alias, name } of champions) {
for (const prefix of keyStrings(name, alias)) { for (const prefix of keyStrings(name, alias)) {
const chars = Object.assign(Array(4).fill('\\0'), Array.from(prefix))
.map(c => `'${c}'`)
.map(c => c.padStart(4));
}} }}
0x{{= strHash(prefix).toString(16).padEnd(8) }} /* {{= prefix.padEnd(4) }} */ => Ok(Champion::{{= constName(name) }}), /* {{= prefix.padEnd(4) }} */ [{{= chars.join(', ') }}] => Ok(Champion::{{= constName(name) }}),
{{ {{
} }
} }
}} }}
_ => Err(()), unknown => Err(ParseChampionError(unknown)),
} }
} }
} }

View File

@ -40,6 +40,12 @@ pub async fn match_v5_get(route: RegionalRoute, matches: &[&'static str]) -> Res
if m.metadata.participants.is_empty() { if m.metadata.participants.is_empty() {
return Err("Match should have participants.".to_owned()); return Err("Match should have participants.".to_owned());
} }
if m.metadata.participants.len() != m.info.participants.len() {
return Err("Match participants do not line up with participant UUIDs.".to_owned());
}
for participant in &m.info.participants {
participant.champion().map_err(|e| format!("Failed to determine champion: {}", e))?;
}
if m.info.teams.is_empty() { if m.info.teams.is_empty() {
return Err("Match should have teams.".to_owned()); return Err("Match should have teams.".to_owned());
} }