use std::fmt::{Display, Formatter};
use std::ops::{Add, AddAssign};
#[derive(Debug, Clone, Copy)]
pub enum Key {
Null,
Cancel,
Help,
Backspace,
Tab,
Clear,
Return,
Enter,
Shift,
Control,
Alt,
Pause,
Escape,
Space,
PageUp,
PageDown,
End,
Home,
Left,
Up,
Right,
Down,
Insert,
Delete,
Semicolon,
Equals,
NumPad0,
NumPad1,
NumPad2,
NumPad3,
NumPad4,
NumPad5,
NumPad6,
NumPad7,
NumPad8,
NumPad9,
Multiply,
Add,
Separator,
Subtract,
Decimal,
Divide,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
Meta,
Command,
}
impl From<Key> for char {
fn from(k: Key) -> char {
match k {
Key::Null => '\u{e000}',
Key::Cancel => '\u{e001}',
Key::Help => '\u{e002}',
Key::Backspace => '\u{e003}',
Key::Tab => '\u{e004}',
Key::Clear => '\u{e005}',
Key::Return => '\u{e006}',
Key::Enter => '\u{e007}',
Key::Shift => '\u{e008}',
Key::Control => '\u{e009}',
Key::Alt => '\u{e00a}',
Key::Pause => '\u{e00b}',
Key::Escape => '\u{e00c}',
Key::Space => '\u{e00d}',
Key::PageUp => '\u{e00e}',
Key::PageDown => '\u{e00f}',
Key::End => '\u{e010}',
Key::Home => '\u{e011}',
Key::Left => '\u{e012}',
Key::Up => '\u{e013}',
Key::Right => '\u{e014}',
Key::Down => '\u{e015}',
Key::Insert => '\u{e016}',
Key::Delete => '\u{e017}',
Key::Semicolon => '\u{e018}',
Key::Equals => '\u{e019}',
Key::NumPad0 => '\u{e01a}',
Key::NumPad1 => '\u{e01b}',
Key::NumPad2 => '\u{e01c}',
Key::NumPad3 => '\u{e01d}',
Key::NumPad4 => '\u{e01e}',
Key::NumPad5 => '\u{e01f}',
Key::NumPad6 => '\u{e020}',
Key::NumPad7 => '\u{e021}',
Key::NumPad8 => '\u{e022}',
Key::NumPad9 => '\u{e023}',
Key::Multiply => '\u{e024}',
Key::Add => '\u{e025}',
Key::Separator => '\u{e026}',
Key::Subtract => '\u{e027}',
Key::Decimal => '\u{e028}',
Key::Divide => '\u{e029}',
Key::F1 => '\u{e031}',
Key::F2 => '\u{e032}',
Key::F3 => '\u{e033}',
Key::F4 => '\u{e034}',
Key::F5 => '\u{e035}',
Key::F6 => '\u{e036}',
Key::F7 => '\u{e037}',
Key::F8 => '\u{e038}',
Key::F9 => '\u{e039}',
Key::F10 => '\u{e03a}',
Key::F11 => '\u{e03b}',
Key::F12 => '\u{e03c}',
Key::Meta => '\u{e03d}',
Key::Command => '\u{e03d}',
}
}
}
impl Display for Key {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", char::from(*self))
}
}
impl Add<Key> for String {
type Output = String;
fn add(mut self, rhs: Key) -> Self::Output {
self.push(rhs.into());
self
}
}
impl AddAssign<Key> for String {
fn add_assign(&mut self, rhs: Key) {
self.push(rhs.into());
}
}
impl Add<String> for Key {
type Output = String;
fn add(self, rhs: String) -> Self::Output {
format!("{}{}", char::from(self), rhs)
}
}
impl Add<Key> for Key {
type Output = String;
fn add(self, rhs: Key) -> Self::Output {
format!("{}{}", char::from(self), char::from(rhs))
}
}
impl Add<&str> for Key {
type Output = String;
fn add(self, rhs: &str) -> Self::Output {
format!("{}{}", char::from(self), rhs)
}
}
impl Add<Key> for &str {
type Output = String;
fn add(self, rhs: Key) -> Self::Output {
format!("{}{}", self, char::from(rhs))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_keys() {
assert_eq!(Key::Control + Key::Shift, "\u{e009}\u{e008}".to_string());
}
#[test]
fn test_key_str() {
assert_eq!(Key::Control + "a", "\u{e009}a".to_string());
assert_eq!("a" + Key::Control, "a\u{e009}".to_string());
}
#[test]
fn test_key_string() {
assert_eq!(Key::Control + "a".to_string(), "\u{e009}a".to_string());
assert_eq!("a".to_string() + Key::Control, "a\u{e009}".to_string());
}
#[test]
fn test_string_addassign() {
let mut k = String::new();
k += Key::Control;
assert_eq!(k, "\u{e009}".to_string());
let mut k = "test".to_string();
k += Key::Control;
assert_eq!(k, "test\u{e009}".to_string());
}
#[test]
fn test_key_key_string() {
assert_eq!(
Key::Control + Key::Alt + "e",
"\u{e009}\u{e00a}e".to_string()
);
}
}