Skip to main content

keytap/
lib.rs

1//! keytap — cross-platform, observe-only global keyboard taps.
2//!
3//! See `DESIGN.md` in the repository root for the full architecture.
4//!
5//! ```no_run
6//! use keytap::{Tap, EventKind, Key};
7//!
8//! # fn main() -> Result<(), keytap::Error> {
9//! let tap = Tap::new()?;
10//! for event in tap.iter() {
11//!     if let EventKind::KeyDown(Key::MetaRight) = event.kind {
12//!         println!("Right-⌘ pressed");
13//!     }
14//! }
15//! # Ok(()) }
16//! ```
17
18#![warn(missing_debug_implementations)]
19#![allow(dead_code)] // scaffolding — impls land in subsequent commits
20
21pub use crossbeam_channel::{RecvError, RecvTimeoutError, TryRecvError};
22
23mod error;
24mod event;
25mod key;
26mod log;
27mod platform;
28mod tap;
29
30#[cfg(feature = "chord")]
31pub mod chord;
32
33pub use error::Error;
34pub use event::{Event, EventKind};
35pub use key::{Key, RawCode};
36pub use tap::{Tap, TapBuilder, TapIter};
37
38// Compile-time guarantees that the public types used across threads are
39// actually thread-safe. If someone ever changes `Tap` / `ChordMatcher` so
40// they're no longer `Send + Sync`, the build breaks here instead of at
41// some distant user site.
42#[allow(dead_code)]
43const fn assert_send_sync<T: Send + Sync>() {}
44
45const _ASSERT_TAP_SEND_SYNC: () = assert_send_sync::<Tap>();
46const _ASSERT_EVENT_SEND: () = assert_send_sync::<Event>();
47const _ASSERT_KEY_SEND: () = assert_send_sync::<Key>();
48const _ASSERT_ERROR_SEND: () = assert_send_sync::<Error>();
49
50#[cfg(feature = "chord")]
51const _ASSERT_CHORD_MATCHER_SEND_SYNC: () = assert_send_sync::<chord::ChordMatcher<&'static str>>();
52#[cfg(feature = "chord")]
53const _ASSERT_CHORD_SEND: () = assert_send_sync::<chord::Chord>();
54#[cfg(feature = "chord")]
55const _ASSERT_CHORD_MODE_SEND: () = assert_send_sync::<chord::ChordMode>();