use std::collections::HashSet;
use promkit_widgets::core::crossterm::event::{
Event, KeyCode, KeyEvent, KeyModifiers, MouseEvent, MouseEventKind,
};
use serde::{Deserialize, Serialize};
pub trait Matcher<T> {
fn matches(&self, other: &T) -> bool;
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct EventDefSet(HashSet<EventDef>);
impl Matcher<Event> for EventDefSet {
fn matches(&self, other: &Event) -> bool {
self.0.iter().any(|event_def| event_def.matches(other))
}
}
impl FromIterator<EventDef> for EventDefSet {
fn from_iter<I: IntoIterator<Item = EventDef>>(iter: I) -> Self {
EventDefSet(iter.into_iter().collect())
}
}
impl From<KeyEventDef> for EventDefSet {
fn from(key_event_def: KeyEventDef) -> Self {
EventDefSet(HashSet::from_iter([EventDef::Key(key_event_def)]))
}
}
impl From<MouseEventDef> for EventDefSet {
fn from(mouse_event_def: MouseEventDef) -> Self {
EventDefSet(HashSet::from_iter([EventDef::Mouse(mouse_event_def)]))
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub enum EventDef {
Key(KeyEventDef),
Mouse(MouseEventDef),
}
impl Matcher<Event> for EventDef {
fn matches(&self, other: &Event) -> bool {
match (self, other) {
(EventDef::Key(key_def), Event::Key(key_event)) => key_def.matches(key_event),
(EventDef::Mouse(mouse_def), Event::Mouse(mouse_event)) => {
mouse_def.matches(mouse_event)
}
_ => false,
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct KeyEventDef {
code: KeyCode,
modifiers: KeyModifiers,
}
impl KeyEventDef {
pub fn new(code: KeyCode, modifiers: KeyModifiers) -> Self {
KeyEventDef { code, modifiers }
}
}
impl Matcher<KeyEvent> for KeyEventDef {
fn matches(&self, other: &KeyEvent) -> bool {
self.code == other.code && self.modifiers == other.modifiers
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct MouseEventDef {
kind: MouseEventKind,
modifiers: KeyModifiers,
}
impl MouseEventDef {
#[allow(dead_code)]
pub fn new(kind: MouseEventKind, modifiers: KeyModifiers) -> Self {
MouseEventDef { kind, modifiers }
}
}
impl Matcher<MouseEvent> for MouseEventDef {
fn matches(&self, other: &MouseEvent) -> bool {
self.kind == other.kind && self.modifiers == other.modifiers
}
}