use crate::errors::Chip8Error;
use std::convert::TryFrom;
use std::ops::{Index, IndexMut};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum KeyState {
NotPressed = 0,
Pressed = 1,
}
impl Default for KeyState {
#[must_use]
fn default() -> Self {
Self::NotPressed
}
}
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Key {
Key0 = 0x0,
Key1 = 0x1,
Key2 = 0x2,
Key3 = 0x3,
Key4 = 0x4,
Key5 = 0x5,
Key6 = 0x6,
Key7 = 0x7,
Key8 = 0x8,
Key9 = 0x9,
KeyA = 0xA,
KeyB = 0xB,
KeyC = 0xC,
KeyD = 0xD,
KeyE = 0xE,
KeyF = 0xF,
}
impl TryFrom<u8> for Key {
type Error = Chip8Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0x0 => Ok(Self::Key0),
0x1 => Ok(Self::Key1),
0x2 => Ok(Self::Key2),
0x3 => Ok(Self::Key3),
0x4 => Ok(Self::Key4),
0x5 => Ok(Self::Key5),
0x6 => Ok(Self::Key6),
0x7 => Ok(Self::Key7),
0x8 => Ok(Self::Key8),
0x9 => Ok(Self::Key9),
0xA => Ok(Self::KeyA),
0xB => Ok(Self::KeyB),
0xC => Ok(Self::KeyC),
0xD => Ok(Self::KeyD),
0xE => Ok(Self::KeyE),
0xF => Ok(Self::KeyF),
_ => Err(Chip8Error::InvalidKey(value)),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Keypad {
state: [KeyState; 16],
}
impl Keypad {
#[must_use]
pub fn new() -> Self {
Self {
state: [KeyState::default(); 16],
}
}
}
impl Index<Key> for Keypad {
type Output = KeyState;
#[must_use]
fn index(&self, index: Key) -> &Self::Output {
&self.state[index as usize]
}
}
impl IndexMut<Key> for Keypad {
#[must_use]
fn index_mut(&mut self, index: Key) -> &mut Self::Output {
&mut self.state[index as usize]
}
}
impl Default for Keypad {
#[must_use]
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn keypad_default() {
use super::{Key::*, KeyState::*};
let keypad = Keypad::default();
assert_eq!(keypad[Key0], NotPressed);
assert_eq!(keypad[Key1], NotPressed);
assert_eq!(keypad[Key2], NotPressed);
assert_eq!(keypad[Key3], NotPressed);
assert_eq!(keypad[Key4], NotPressed);
assert_eq!(keypad[Key5], NotPressed);
assert_eq!(keypad[Key6], NotPressed);
assert_eq!(keypad[Key7], NotPressed);
assert_eq!(keypad[Key8], NotPressed);
assert_eq!(keypad[Key9], NotPressed);
assert_eq!(keypad[KeyA], NotPressed);
assert_eq!(keypad[KeyB], NotPressed);
assert_eq!(keypad[KeyC], NotPressed);
assert_eq!(keypad[KeyD], NotPressed);
assert_eq!(keypad[KeyE], NotPressed);
assert_eq!(keypad[KeyF], NotPressed);
}
}