#![no_std]
#![deny(clippy::unwrap_used)]
#![warn(missing_docs, missing_debug_implementations)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![doc = include_str!("../README.md")]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "std")]
mod encoder;
mod key;
mod mouse;
#[cfg(feature = "std")]
mod parser;
use alloc::string::String;
use core::error::Error;
use core::fmt;
#[cfg(feature = "std")]
pub use encoder::*;
pub use key::*;
pub use mouse::*;
#[derive(Debug)]
pub struct UnsupportedEvent(pub String);
impl fmt::Display for UnsupportedEvent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Unsupported event: {}", self.0)
}
}
impl Error for UnsupportedEvent {}
#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Event {
FocusGained,
FocusLost,
Key(KeyEvent),
Mouse(MouseEvent),
Paste(String),
Resize {
rows: u32,
cols: u32,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Repeats {
Include,
Exclude,
}
impl Event {
pub fn as_key(&self) -> Option<KeyEvent> {
if let Self::Key(key_event) = self {
Some(*key_event)
} else {
None
}
}
pub fn is_key(&self) -> bool {
self.as_key().is_some()
}
pub fn as_key_press(&self, repeats: Repeats) -> Option<KeyEvent> {
if repeats == Repeats::Include {
if let Self::Key(
key_event @ KeyEvent {
kind: KeyEventKind::Press | KeyEventKind::Repeat,
..
},
) = self
{
Some(*key_event)
} else {
None
}
} else if let Self::Key(
key_event @ KeyEvent {
kind: KeyEventKind::Press,
..
},
) = self
{
Some(*key_event)
} else {
None
}
}
pub fn is_key_press(&self, repeats: Repeats) -> bool {
self.as_key_press(repeats).is_some()
}
pub fn as_key_repeat(&self) -> Option<KeyEvent> {
if let Self::Key(
key_event @ KeyEvent {
kind: KeyEventKind::Repeat,
..
},
) = self
{
Some(*key_event)
} else {
None
}
}
pub fn is_key_repeat(&self) -> bool {
self.as_key_repeat().is_some()
}
pub fn as_key_release(&self) -> Option<KeyEvent> {
if let Self::Key(
key_event @ KeyEvent {
kind: KeyEventKind::Release,
..
},
) = self
{
Some(*key_event)
} else {
None
}
}
pub fn is_key_release(&self) -> bool {
self.as_key_release().is_some()
}
pub fn as_mouse(&self) -> Option<MouseEvent> {
if let Self::Mouse(mouse_event) = self {
Some(*mouse_event)
} else {
None
}
}
pub fn is_mouse(&self) -> bool {
self.as_mouse().is_some()
}
pub fn as_mouse_down(&self) -> Option<(MouseEvent, MouseButton)> {
if let Self::Mouse(
mouse_event @ MouseEvent {
kind: MouseEventKind::Down(button),
..
},
) = self
{
Some((*mouse_event, *button))
} else {
None
}
}
pub fn is_mouse_down(&self) -> bool {
self.as_mouse_down().is_some()
}
pub fn as_mouse_up(&self) -> Option<(MouseEvent, MouseButton)> {
if let Self::Mouse(
mouse_event @ MouseEvent {
kind: MouseEventKind::Up(button),
..
},
) = self
{
Some((*mouse_event, *button))
} else {
None
}
}
pub fn is_mouse_up(&self) -> bool {
self.as_mouse_up().is_some()
}
pub fn as_mouse_drag(&self) -> Option<(MouseEvent, MouseButton)> {
if let Self::Mouse(
mouse_event @ MouseEvent {
kind: MouseEventKind::Drag(button),
..
},
) = self
{
Some((*mouse_event, *button))
} else {
None
}
}
pub fn is_mouse_drag(&self) -> bool {
self.as_mouse_drag().is_some()
}
pub fn as_mouse_move(&self) -> Option<MouseEvent> {
if let Self::Mouse(
mouse_event @ MouseEvent {
kind: MouseEventKind::Moved,
..
},
) = self
{
Some(*mouse_event)
} else {
None
}
}
pub fn is_mouse_move(&self) -> bool {
self.as_mouse_move().is_some()
}
pub fn as_mouse_scroll(&self) -> Option<(MouseEvent, ScrollDirection)> {
if let Self::Mouse(
mouse_event @ MouseEvent {
kind: MouseEventKind::Scroll(direction),
..
},
) = self
{
Some((*mouse_event, *direction))
} else {
None
}
}
pub fn is_mouse_scroll(&self) -> bool {
self.as_mouse_scroll().is_some()
}
pub fn is_focus_gained(&self) -> bool {
*self == Self::FocusGained
}
pub fn is_focus_lost(&self) -> bool {
*self == Self::FocusLost
}
pub fn as_paste(&self) -> Option<&str> {
if let Self::Paste(text) = self {
Some(text)
} else {
None
}
}
pub fn is_paste(&self) -> bool {
self.as_paste().is_some()
}
pub fn as_resize(&self) -> Option<(u32, u32)> {
if let Self::Resize { rows, cols } = self {
Some((*rows, *cols))
} else {
None
}
}
pub fn is_resize(&self) -> bool {
self.as_resize().is_some()
}
}