use core::str::FromStr;
use crate::utils::{ConversionError, UNIT_LETTER_MAP};
use super::utils::{Letter, LetterMapping};
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub struct Plugboard {
steckerverbindungen: LetterMapping,
}
impl Default for Plugboard {
fn default() -> Self {
Plugboard {
steckerverbindungen: UNIT_LETTER_MAP,
}
}
}
impl Plugboard {
#[must_use]
pub fn new(pairs: &[(Letter, Letter)]) -> Self {
let mut new = Plugboard::default();
pairs.iter().for_each(|&pair| new.add_cable(pair));
new
}
pub fn remove_cable(&mut self, pair: (Letter, Letter)) {
self.steckerverbindungen[pair.0] = pair.0;
self.steckerverbindungen[pair.1] = pair.1;
}
pub fn add_cable(&mut self, pair: (Letter, Letter)) {
debug!("adding {:?} and {:?}", pair.0, pair.1);
self.steckerverbindungen[pair.0] = pair.1;
self.steckerverbindungen[pair.1] = pair.0;
}
}
impl FromStr for Plugboard {
type Err = ConversionError;
fn from_str(string: &str) -> Result<Plugboard, Self::Err> {
let mut plugboard = Plugboard::new(&[]);
let mut a = string
.chars()
.filter(|x| ![',', '-', ' '].contains(x))
.map(Letter::try_from);
while let Some(x) = a.next() {
if let Some(y) = a.next() {
plugboard.add_cable((x?, y?));
}
}
debug!("{plugboard:?}");
Ok(plugboard)
}
}
impl core::ops::Index<Letter> for Plugboard {
type Output = Letter;
fn index(&self, index: Letter) -> &Self::Output {
&self.steckerverbindungen[index]
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new() {
let plugboard = Plugboard::new(&[(Letter::A, Letter::B), (Letter::X, Letter::Y)]);
assert_eq!(plugboard[Letter::A], Letter::B);
assert_eq!(plugboard[Letter::B], Letter::A);
assert_eq!(plugboard[Letter::X], Letter::Y);
assert_eq!(plugboard[Letter::G], Letter::G);
}
#[test]
fn test_string_to_plugboard() {
let plugboard = Plugboard::from_str("EN,IG,MA").unwrap();
assert_eq!(plugboard[Letter::N], Letter::E);
assert_eq!(plugboard[Letter::E], Letter::N);
}
}