KeyEvent case normalizing equality (#541)
This commit is contained in:
parent
58f580eaad
commit
92f62ba86f
82
src/event.rs
82
src/event.rs
@ -73,6 +73,7 @@
|
|||||||
//! them (`event-*`).
|
//! them (`event-*`).
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
@ -385,7 +386,7 @@ bitflags! {
|
|||||||
|
|
||||||
/// Represents a key event.
|
/// Represents a key event.
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]
|
#[derive(Debug, PartialOrd, Clone, Copy)]
|
||||||
pub struct KeyEvent {
|
pub struct KeyEvent {
|
||||||
/// The key itself.
|
/// The key itself.
|
||||||
pub code: KeyCode,
|
pub code: KeyCode,
|
||||||
@ -397,6 +398,23 @@ impl KeyEvent {
|
|||||||
pub fn new(code: KeyCode, modifiers: KeyModifiers) -> KeyEvent {
|
pub fn new(code: KeyCode, modifiers: KeyModifiers) -> KeyEvent {
|
||||||
KeyEvent { code, modifiers }
|
KeyEvent { code, modifiers }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// modifies the KeyEvent,
|
||||||
|
// so that KeyModifiers::SHIFT is present iff
|
||||||
|
// an uppercase char is present.
|
||||||
|
fn normalize_case(mut self) -> KeyEvent {
|
||||||
|
let c = match self.code {
|
||||||
|
KeyCode::Char(c) => c,
|
||||||
|
_ => return self,
|
||||||
|
};
|
||||||
|
|
||||||
|
if c.is_ascii_uppercase() {
|
||||||
|
self.modifiers.insert(KeyModifiers::SHIFT);
|
||||||
|
} else if self.modifiers.contains(KeyModifiers::SHIFT) {
|
||||||
|
self.code = KeyCode::Char(c.to_ascii_uppercase())
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<KeyCode> for KeyEvent {
|
impl From<KeyCode> for KeyEvent {
|
||||||
@ -408,6 +426,30 @@ impl From<KeyCode> for KeyEvent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq for KeyEvent {
|
||||||
|
fn eq(&self, other: &KeyEvent) -> bool {
|
||||||
|
let KeyEvent {
|
||||||
|
code: lhs_code,
|
||||||
|
modifiers: lhs_modifiers,
|
||||||
|
} = self.normalize_case();
|
||||||
|
let KeyEvent {
|
||||||
|
code: rhs_code,
|
||||||
|
modifiers: rhs_modifiers,
|
||||||
|
} = other.normalize_case();
|
||||||
|
(lhs_code == rhs_code) && (lhs_modifiers == rhs_modifiers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for KeyEvent {}
|
||||||
|
|
||||||
|
impl Hash for KeyEvent {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
let KeyEvent { code, modifiers } = self.normalize_case();
|
||||||
|
code.hash(state);
|
||||||
|
modifiers.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Represents a key.
|
/// Represents a key.
|
||||||
#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]
|
#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
@ -466,3 +508,41 @@ pub(crate) enum InternalEvent {
|
|||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
CursorPosition(u16, u16),
|
CursorPosition(u16, u16),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::collections::hash_map::DefaultHasher;
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
|
|
||||||
|
use super::{KeyCode, KeyEvent, KeyModifiers};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_equality() {
|
||||||
|
let lowercase_d_with_shift = KeyEvent::new(KeyCode::Char('d'), KeyModifiers::SHIFT);
|
||||||
|
let uppercase_d_with_shift = KeyEvent::new(KeyCode::Char('D'), KeyModifiers::SHIFT);
|
||||||
|
let uppercase_d = KeyEvent::new(KeyCode::Char('D'), KeyModifiers::NONE);
|
||||||
|
assert_eq!(lowercase_d_with_shift, uppercase_d_with_shift);
|
||||||
|
assert_eq!(uppercase_d, uppercase_d_with_shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_hash() {
|
||||||
|
let lowercase_d_with_shift_hash = {
|
||||||
|
let mut hasher = DefaultHasher::new();
|
||||||
|
KeyEvent::new(KeyCode::Char('d'), KeyModifiers::SHIFT).hash(&mut hasher);
|
||||||
|
hasher.finish()
|
||||||
|
};
|
||||||
|
let uppercase_d_with_shift_hash = {
|
||||||
|
let mut hasher = DefaultHasher::new();
|
||||||
|
KeyEvent::new(KeyCode::Char('D'), KeyModifiers::SHIFT).hash(&mut hasher);
|
||||||
|
hasher.finish()
|
||||||
|
};
|
||||||
|
let uppercase_d_hash = {
|
||||||
|
let mut hasher = DefaultHasher::new();
|
||||||
|
KeyEvent::new(KeyCode::Char('D'), KeyModifiers::NONE).hash(&mut hasher);
|
||||||
|
hasher.finish()
|
||||||
|
};
|
||||||
|
assert_eq!(lowercase_d_with_shift_hash, uppercase_d_with_shift_hash);
|
||||||
|
assert_eq!(uppercase_d_hash, uppercase_d_with_shift_hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user