use crate::alphabet::ALPHABET;
use strum::IntoEnumIterator;
#[derive(strum_macros::EnumIter, PartialEq, Eq, Hash)]
pub enum Reflector {
A,
B,
C,
BThin,
CThin,
Ukwr,
Ukwk,
}
static REFLECTORS: std::sync::OnceLock<std::collections::HashMap<Reflector, std::collections::HashMap<char, char>>> = std::sync::OnceLock::new();
impl Reflector {
pub fn alphabet(&self) -> &std::collections::HashMap<char, char> {
REFLECTORS
.get_or_init(|| {
let mut reflectors = std::collections::HashMap::new();
for reflector in Self::iter() {
let alphabet = match self {
Self::A => "EJMZALYXVBWFCRQUONTSPIKHGD",
Self::B => "YRUHQSLDPXNGOKMIEBFZCWVJAT",
Self::C => "FVPJIAOYEDRZXWGCTKUQSBNMHL",
Self::BThin => "ENKQAUYWJICOPBLMDXZVFTHRGS",
Self::CThin => "RDOBJNTKVEHMLFCWZAXGYIPSUQ",
Self::Ukwr => "QYHOGNECVPUZTFDJAXWMKISRBL",
Self::Ukwk => "IMETCGFRAYSQBZXWLHKDVUPOJN",
};
let mut map = std::collections::HashMap::new();
for (letter, reflected_letter) in ALPHABET.letters().chars().zip(alphabet.chars()) {
map.insert(letter, reflected_letter);
map.insert(reflected_letter, letter);
}
reflectors.insert(reflector, map);
}
reflectors
})
.get(self)
.unwrap()
}
}
impl TryFrom<&str> for Reflector {
type Error = anyhow::Error;
fn try_from(value: &str) -> Result<Self, Self::Error> {
Ok(match value.to_lowercase().as_str() {
"a" => Self::A,
"b" => Self::B,
"c" => Self::C,
"bthin" => Self::BThin,
"cthin" => Self::CThin,
"ukwr" => Self::Ukwr,
"ukwk" => Self::Ukwk,
_ => anyhow::bail!("Invalid reflector: {value}"),
})
}
}