use crossterm::event::KeyEvent; use std::fmt; use std::sync::mpsc; #[derive(Debug)] pub enum EventError { Send(Event), Recv, Io(std::io::Error), } impl fmt::Display for EventError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Self::Send(ref e) => write!(f, "failed to send event: {e:?}"), Self::Recv => write!(f, "receive event call failed"), Self::Io(ref e) => { write!(f, "an I/O error was triggered during event handling: {e}") } } } } impl From> for EventError { fn from(err: mpsc::SendError) -> EventError { EventError::Send(err.0) } } impl From for EventError { fn from(_: mpsc::RecvError) -> EventError { EventError::Recv } } #[derive(Clone, Copy, Debug)] pub enum Event { Key(KeyEvent), } pub struct EventChannel { sender: mpsc::Sender, receiver: mpsc::Receiver, } pub struct EventSender { sender: mpsc::Sender, } pub struct EventReceiver { receiver: mpsc::Receiver, } impl EventChannel { pub fn new() -> Self { let (sender, receiver) = mpsc::channel(); EventChannel { sender, receiver } } pub fn sender(&self) -> EventSender { EventSender { sender: self.sender.clone(), } } pub fn receiver(self) -> EventReceiver { EventReceiver { receiver: self.receiver, } } } impl EventSender { pub fn send(&self, event: Event) -> Result<(), EventError> { Ok(self.sender.send(event)?) } } impl EventReceiver { pub fn recv(&self) -> Result { Ok(self.receiver.recv()?) } } #[cfg(test)] mod tests { use std::io; use crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyEventState, KeyModifiers}; use super::*; #[test] fn event_sender() { let channel = EventChannel::new(); let sender = channel.sender(); let receiver = channel.receiver(); let event = Event::Key(KeyEvent::new(KeyCode::Up, KeyModifiers::empty())); let result = sender.send(event); assert!(result.is_ok()); drop(receiver); let result = sender.send(event); assert!(result.is_err()); } #[test] fn event_receiver() { let channel = EventChannel::new(); let sender = channel.sender(); let receiver = channel.receiver(); let event = Event::Key(KeyEvent::new(KeyCode::Up, KeyModifiers::empty())); sender.send(event).unwrap(); let result = receiver.recv(); assert!(result.is_ok()); drop(sender); let result = receiver.recv(); assert!(result.is_err()); } #[test] fn errors() { let send_err = EventError::Send(Event::Key(KeyEvent { code: KeyCode::Up, modifiers: KeyModifiers::empty(), kind: KeyEventKind::Press, state: KeyEventState::NONE, })); let recv_err = EventError::Recv; let io_err = EventError::Io(io::Error::new(io::ErrorKind::Interrupted, "interrupted")); assert!(!send_err.to_string().is_empty()); assert!(!recv_err.to_string().is_empty()); assert!(!io_err.to_string().is_empty()); assert!(!format!("{:?}", send_err).is_empty()); assert!(!format!("{:?}", recv_err).is_empty()); assert!(!format!("{:?}", io_err).is_empty()); } }