use crate::key_code::KeyCode;
use crate::layout::{StackedIter, WaitingAction};
use core::fmt::Debug;
#[non_exhaustive]
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum SequenceEvent<T: 'static> {
NoOp,
Press(KeyCode),
Release(KeyCode),
Tap(KeyCode),
Delay {
duration: u32, },
Continue {
index: usize,
events: &'static [SequenceEvent<T>],
},
Custom(&'static T),
Complete,
}
impl<T> Debug for SequenceEvent<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::NoOp => write!(f, "NoOp"),
Self::Press(arg0) => f.debug_tuple("Press").field(arg0).finish(),
Self::Release(arg0) => f.debug_tuple("Release").field(arg0).finish(),
Self::Tap(arg0) => f.debug_tuple("Tap").field(arg0).finish(),
Self::Delay { duration } => {
f.debug_struct("Delay").field("duration", duration).finish()
}
Self::Continue { index, events } => f
.debug_struct("Continue")
.field("index", index)
.field("events", events)
.finish(),
Self::Custom(_) => write!(f, "Custom"),
Self::Complete => write!(f, "Complete"),
}
}
}
#[non_exhaustive]
#[derive(Clone, Copy)]
pub enum HoldTapConfig {
Default,
HoldOnOtherKeyPress,
PermissiveHold,
Custom(fn(StackedIter) -> Option<WaitingAction>),
}
impl Debug for HoldTapConfig {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
HoldTapConfig::Default => f.write_str("Default"),
HoldTapConfig::HoldOnOtherKeyPress => f.write_str("HoldOnOtherKeyPress"),
HoldTapConfig::PermissiveHold => f.write_str("PermissiveHold"),
HoldTapConfig::Custom(func) => f
.debug_tuple("Custom")
.field(&(*func as fn(StackedIter<'static>) -> Option<WaitingAction>) as &dyn Debug)
.finish(),
}
}
}
impl PartialEq for HoldTapConfig {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(HoldTapConfig::Default, HoldTapConfig::Default)
| (HoldTapConfig::HoldOnOtherKeyPress, HoldTapConfig::HoldOnOtherKeyPress)
| (HoldTapConfig::PermissiveHold, HoldTapConfig::PermissiveHold) => true,
(HoldTapConfig::Custom(self_func), HoldTapConfig::Custom(other_func)) => {
*self_func as fn(StackedIter<'static>) -> Option<WaitingAction> == *other_func
}
_ => false,
}
}
}
impl Eq for HoldTapConfig {}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ReleasableState {
KeyCode(KeyCode),
Layer(usize),
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct HoldTapAction<T>
where
T: 'static,
{
pub timeout: u16,
pub hold: Action<T>,
pub tap: Action<T>,
pub config: HoldTapConfig,
pub tap_hold_interval: u16,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct OneShot<T = core::convert::Infallible>
where
T: 'static,
{
pub action: &'static Action<T>,
pub timeout: u16,
pub end_config: OneShotEndConfig,
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum OneShotEndConfig {
EndOnFirstPress,
EndOnFirstRelease,
}
pub const ONE_SHOT_MAX_ACTIVE: usize = 8;
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct TapDance<T = core::convert::Infallible>
where
T: 'static,
{
pub actions: &'static [&'static Action<T>],
pub timeout: u16,
pub config: TapDanceConfig,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum TapDanceConfig {
Lazy,
Eager,
}
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub enum Action<T = core::convert::Infallible>
where
T: 'static,
{
NoOp,
Trans,
KeyCode(KeyCode),
MultipleKeyCodes(&'static [KeyCode]),
MultipleActions(&'static [Action<T>]),
Layer(usize),
DefaultLayer(usize),
Sequence {
events: &'static [SequenceEvent<T>],
},
CancelSequences,
ReleaseState(ReleasableState),
HoldTap(&'static HoldTapAction<T>),
Custom(T),
OneShot(&'static OneShot<T>),
TapDance(&'static TapDance<T>),
}
impl<T> Action<T> {
pub fn layer(self) -> Option<usize> {
match self {
Action::Layer(l) => Some(l),
_ => None,
}
}
pub fn key_codes(&self) -> impl Iterator<Item = KeyCode> + '_ {
match self {
Action::KeyCode(kc) => core::slice::from_ref(kc).iter().cloned(),
Action::MultipleKeyCodes(kcs) => kcs.iter().cloned(),
_ => [].iter().cloned(),
}
}
}
pub const fn k<T>(kc: KeyCode) -> Action<T> {
Action::KeyCode(kc)
}
pub const fn l<T>(layer: usize) -> Action<T> {
Action::Layer(layer)
}
pub const fn d<T>(layer: usize) -> Action<T> {
Action::DefaultLayer(layer)
}
pub const fn m<T>(kcs: &'static &'static [KeyCode]) -> Action<T> {
Action::MultipleKeyCodes(kcs)
}