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,
}
#[derive(Clone, Copy, Eq, PartialEq)]
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> Debug for Action<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::NoOp => write!(f, "NoOp"),
Self::Trans => write!(f, "Trans"),
Self::KeyCode(arg0) => f.debug_tuple("KeyCode").field(arg0).finish(),
Self::MultipleKeyCodes(arg0) => f.debug_tuple("MultipleKeyCodes").field(arg0).finish(),
Self::MultipleActions(arg0) => f.debug_tuple("MultipleActions").field(arg0).finish(),
Self::Layer(arg0) => f.debug_tuple("Layer").field(arg0).finish(),
Self::DefaultLayer(arg0) => f.debug_tuple("DefaultLayer").field(arg0).finish(),
Self::HoldTap(HoldTapAction {
timeout,
hold,
tap,
config,
tap_hold_interval,
}) => f
.debug_struct("HoldTap")
.field("timeout", timeout)
.field("hold", hold)
.field("tap", tap)
.field("config", config)
.field("tap_hold_interval", tap_hold_interval)
.finish(),
Self::Sequence { events } => {
f.debug_struct("Sequence").field("events", events).finish()
}
Self::CancelSequences => write!(f, "CancelSequences"),
Self::OneShot(OneShot {
action,
timeout,
end_config,
}) => f
.debug_struct("OneShot")
.field("action", action)
.field("timeout", timeout)
.field("end_config", end_config)
.finish(),
Self::TapDance(TapDance { actions, timeout }) => f
.debug_struct("TapDance")
.field("actions", actions)
.field("timeout", timeout)
.finish(),
Self::Custom(_) => f.debug_tuple("Custom").finish(),
Self::ReleaseState(arg0) => f.debug_tuple("ReleaseState").field(arg0).finish(),
}
}
}
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)
}