#![no_std]
#![feature(let_chains)]
#[macro_use]
extern crate static_assertions;
#[macro_use]
extern crate enum_primitive_derive;
extern crate num_traits;
mod converters;
pub mod layout;
pub mod macros;
pub use kll_hid;
#[cfg(feature = "defmt")]
use defmt::{error, trace, warn};
#[cfg(not(feature = "defmt"))]
use log::{error, trace, warn};
pub mod hid {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum Protocol {
Boot = 0,
Application = 1,
Toggle = 3,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum State {
Active = 0,
Inactive = 1,
}
}
pub mod layer {
use core::ops::{BitAnd, BitAndAssign, BitOrAssign, Not};
use num_traits::FromPrimitive;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum Direction {
Next = 0,
Previous = 1,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Primitive)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum State {
Off = 0x00,
Shift = 0x01,
Latch = 0x02,
ShiftLatch = 0x03,
Lock = 0x04,
ShiftLock = 0x05,
LatchLock = 0x06,
ShiftLatchLock = 0x07,
}
impl State {
pub fn add(mut self, state: State) {
self |= state;
}
pub fn remove(mut self, state: State) {
self &= !(state);
}
pub fn is_set(&self, state: State) -> bool {
if state != State::Off {
*self & state != State::Off
} else {
*self == state
}
}
pub fn active(&self) -> bool {
*self != State::Off
}
pub fn effective(&self) -> bool {
match self {
State::Off => false,
State::Shift => true,
State::Latch => true,
State::Lock => true,
State::ShiftLatch => false,
State::ShiftLock => false,
State::LatchLock => false,
State::ShiftLatchLock => true,
}
}
}
impl BitAnd for State {
type Output = Self;
fn bitand(self, rhs: Self) -> Self::Output {
State::from_u32(self as u32 & rhs as u32).unwrap()
}
}
impl BitAndAssign for State {
fn bitand_assign(&mut self, rhs: Self) {
*self = State::from_u32(*self as u32 & rhs as u32).unwrap()
}
}
impl BitOrAssign for State {
fn bitor_assign(&mut self, rhs: Self) {
*self = State::from_u32(*self as u32 | rhs as u32).unwrap()
}
}
impl Not for State {
type Output = Self;
fn not(self) -> Self::Output {
State::from_u32(!(self as u32)).unwrap()
}
}
}
pub mod pixel {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum GammaControl {
Disable = 0,
Enable = 1,
Toggle = 3,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum AnimationControl {
PauseResume = 0,
ForwardOne = 1,
Forward = 2,
Stop = 3,
Reset = 4,
WipePause = 5,
Pause = 6,
Clear = 7,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum FadeCommand {
Reset = 0,
ResetAll = 1,
BrightnessSet = 2,
BrightnessIncrement = 3,
BrightnessDecrement = 4,
BrightnessDefault = 5,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum PixelTest {
Off = 0,
ChannelSingle = 1,
ChannelSingleRotate = 2,
ChannelSingleRotateReverse = 3,
ChannelFlashAll = 4,
ChannelRoll = 5,
ChannelAllOn = 6,
PixelSingle = 7,
PixelSingleRotate = 8,
PixelSingleRotateReverse = 9,
PixelFlashAll = 10,
PixelRoll = 11,
PixelAllOn = 12,
ScanCodeSingle = 13,
ScanCodeSingleRotate = 14,
ScanCodeSingleRotateReverse = 15,
ScanCodeFlashAll = 16,
ScanCodeRoll = 17,
ScanCodeAllOn = 18,
PositionSingle = 19,
PositionSingleRotate = 20,
PositionSingleRotateReverse = 21,
PositionFlashAll = 22,
PositionRoll = 23,
PositionAllOn = 24,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum LedControl {
BrightnessDecrease = 0,
BrightnessIncrease = 1,
BrightnessSet = 2,
BrightnessDefault = 3,
EnableLeds = 4,
DisableLeds = 5,
ToggleLeds = 6,
FpsSet = 7,
FpsIncrease = 8,
FpsDecrease = 9,
FpsDefault = 10,
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum Capability {
NoOp {
state: CapabilityState,
loop_condition_index: u16,
} = 0,
Rotate {
state: CapabilityState,
loop_condition_index: u16,
index: u8,
increment: i8,
} = 1,
LayerClear {
state: CapabilityState,
loop_condition_index: u16,
} = 2,
LayerState {
state: CapabilityState,
loop_condition_index: u16,
layer: u8,
layer_state: layer::State,
} = 3,
LayerRotate {
state: CapabilityState,
loop_condition_index: u16,
direction: layer::Direction,
} = 4,
HidProtocol {
state: CapabilityState,
loop_condition_index: u16,
mode: hid::Protocol,
} = 5,
HidKeyboard {
state: CapabilityState,
loop_condition_index: u16,
id: kll_hid::Keyboard,
} = 6,
HidKeyboardState {
state: CapabilityState,
loop_condition_index: u16,
id: kll_hid::Keyboard,
key_state: hid::State,
} = 7,
HidConsumerControl {
state: CapabilityState,
loop_condition_index: u16,
id: kll_hid::ConsumerControl,
} = 8,
HidSystemControl {
state: CapabilityState,
loop_condition_index: u16,
id: kll_hid::SystemControl,
} = 9,
McuFlashMode {
state: CapabilityState,
loop_condition_index: u16,
} = 10,
PixelAnimationControl {
state: CapabilityState,
loop_condition_index: u16,
mode: pixel::AnimationControl,
},
PixelAnimationIndex {
state: CapabilityState,
loop_condition_index: u16,
index: u16,
},
PixelFadeControl {
state: CapabilityState,
loop_condition_index: u16,
profile: u8,
command: pixel::FadeCommand,
arg: u8,
},
PixelFadeLayer {
state: CapabilityState,
loop_condition_index: u16,
layer: u8,
},
PixelFadeSet {
state: CapabilityState,
loop_condition_index: u16,
profile: u8,
config: u8,
period: u8,
},
PixelGammaControl {
state: CapabilityState,
loop_condition_index: u16,
mode: pixel::GammaControl,
},
PixelLedControl {
state: CapabilityState,
loop_condition_index: u16,
mode: pixel::LedControl,
amount: u8,
},
PixelTest {
state: CapabilityState,
loop_condition_index: u16,
test: pixel::PixelTest,
index: u16,
},
HidioOpenUrl {
state: CapabilityState,
loop_condition_index: u16,
index: u16,
},
HidioUnicodeString {
state: CapabilityState,
loop_condition_index: u16,
index: u16,
},
HidioUnicodeState {
state: CapabilityState,
loop_condition_index: u16,
unicode: char,
},
}
impl Capability {
pub fn generate(&self, event: TriggerEvent, _loop_condition_lookup: &[u32]) -> CapabilityRun {
match self {
Capability::NoOp { state, .. } => CapabilityRun::NoOp {
state: state.event(event),
},
Capability::HidKeyboard { state, id, .. } => CapabilityRun::HidKeyboard {
state: state.event(event),
id: *id,
},
_ => {
panic!(
"Missing implementation for Capability::generate: {:?}",
self
);
}
}
}
pub fn loop_condition_index(&self) -> u16 {
match self {
Capability::NoOp {
loop_condition_index,
..
} => *loop_condition_index,
Capability::Rotate {
loop_condition_index,
..
} => *loop_condition_index,
Capability::LayerClear {
loop_condition_index,
..
} => *loop_condition_index,
Capability::LayerState {
loop_condition_index,
..
} => *loop_condition_index,
Capability::LayerRotate {
loop_condition_index,
..
} => *loop_condition_index,
Capability::HidProtocol {
loop_condition_index,
..
} => *loop_condition_index,
Capability::HidKeyboard {
loop_condition_index,
..
} => *loop_condition_index,
Capability::HidKeyboardState {
loop_condition_index,
..
} => *loop_condition_index,
Capability::HidConsumerControl {
loop_condition_index,
..
} => *loop_condition_index,
Capability::HidSystemControl {
loop_condition_index,
..
} => *loop_condition_index,
Capability::McuFlashMode {
loop_condition_index,
..
} => *loop_condition_index,
Capability::PixelAnimationControl {
loop_condition_index,
..
} => *loop_condition_index,
Capability::PixelAnimationIndex {
loop_condition_index,
..
} => *loop_condition_index,
Capability::PixelFadeControl {
loop_condition_index,
..
} => *loop_condition_index,
Capability::PixelFadeLayer {
loop_condition_index,
..
} => *loop_condition_index,
Capability::PixelFadeSet {
loop_condition_index,
..
} => *loop_condition_index,
Capability::PixelGammaControl {
loop_condition_index,
..
} => *loop_condition_index,
Capability::PixelLedControl {
loop_condition_index,
..
} => *loop_condition_index,
Capability::PixelTest {
loop_condition_index,
..
} => *loop_condition_index,
Capability::HidioOpenUrl {
loop_condition_index,
..
} => *loop_condition_index,
Capability::HidioUnicodeString {
loop_condition_index,
..
} => *loop_condition_index,
Capability::HidioUnicodeState {
loop_condition_index,
..
} => *loop_condition_index,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum CapabilityRun {
NoOp { state: CapabilityEvent } = 0,
Rotate {
state: CapabilityEvent,
index: u8,
increment: i8,
} = 1,
LayerClear { state: CapabilityEvent } = 2,
LayerState {
state: CapabilityEvent,
layer: u8,
layer_state: layer::State,
} = 3,
LayerRotate {
state: CapabilityEvent,
direction: layer::Direction,
} = 4,
HidProtocol {
state: CapabilityEvent,
mode: hid::Protocol,
} = 5,
HidKeyboard {
state: CapabilityEvent,
id: kll_hid::Keyboard,
} = 6,
HidKeyboardState {
state: CapabilityEvent,
id: kll_hid::Keyboard,
key_state: hid::State,
} = 7,
HidConsumerControl {
state: CapabilityEvent,
id: kll_hid::ConsumerControl,
} = 8,
HidSystemControl {
state: CapabilityEvent,
id: kll_hid::SystemControl,
} = 9,
McuFlashMode { state: CapabilityEvent } = 10,
HidLed {
state: CapabilityEvent,
id: kll_hid::LedIndicator,
} = 11,
PixelAnimationControl {
state: CapabilityEvent,
mode: pixel::AnimationControl,
},
PixelAnimationIndex { state: CapabilityEvent, index: u16 },
PixelFadeControl {
state: CapabilityEvent,
profile: u8,
command: pixel::FadeCommand,
arg: u8,
},
PixelFadeLayer { state: CapabilityEvent, layer: u8 },
PixelFadeSet {
state: CapabilityEvent,
profile: u8,
config: u8,
period: u8,
},
PixelGammaControl {
state: CapabilityEvent,
mode: pixel::GammaControl,
},
PixelLedControl {
state: CapabilityEvent,
mode: pixel::LedControl,
amount: u8,
},
PixelTest {
state: CapabilityEvent,
test: pixel::PixelTest,
index: u16,
},
Analog { state: CapabilityEvent },
HidioOpenUrl { state: CapabilityEvent, index: u16 },
HidioUnicodeString { state: CapabilityEvent, index: u16 },
HidioUnicodeState {
state: CapabilityEvent,
unicode: char,
},
}
impl CapabilityRun {
pub fn state(&self) -> CapabilityEvent {
match self {
CapabilityRun::NoOp { state } => *state,
CapabilityRun::Rotate { state, .. } => *state,
CapabilityRun::LayerClear { state, .. } => *state,
CapabilityRun::LayerState { state, .. } => *state,
CapabilityRun::LayerRotate { state, .. } => *state,
CapabilityRun::HidProtocol { state, .. } => *state,
CapabilityRun::HidKeyboard { state, .. } => *state,
CapabilityRun::HidKeyboardState { state, .. } => *state,
CapabilityRun::HidConsumerControl { state, .. } => *state,
CapabilityRun::HidSystemControl { state, .. } => *state,
CapabilityRun::McuFlashMode { state, .. } => *state,
CapabilityRun::HidLed { state, .. } => *state,
CapabilityRun::PixelAnimationControl { state, .. } => *state,
CapabilityRun::PixelFadeControl { state, .. } => *state,
CapabilityRun::PixelFadeLayer { state, .. } => *state,
CapabilityRun::PixelFadeSet { state, .. } => *state,
CapabilityRun::PixelGammaControl { state, .. } => *state,
CapabilityRun::PixelLedControl { state, .. } => *state,
CapabilityRun::PixelTest { state, .. } => *state,
CapabilityRun::Analog { state } => *state,
CapabilityRun::HidioOpenUrl { state, .. } => *state,
CapabilityRun::HidioUnicodeString { state, .. } => *state,
CapabilityRun::HidioUnicodeState { state, .. } => *state,
_ => {
panic!("CapabilityRun type not handled for state({:?})", self)
}
}
}
}
const_assert_eq!(core::mem::size_of::<Capability>(), 8);
impl Capability {
pub const unsafe fn bytes(&self) -> &[u8] {
&*core::ptr::slice_from_raw_parts(
(self as *const Self) as *const u8,
core::mem::size_of::<Self>(),
)
}
pub const unsafe fn from_byte_array(bytes: [u8; core::mem::size_of::<Self>()]) -> Self {
core::mem::transmute(bytes)
}
pub const unsafe fn from_bytes(bytes: &[u8]) -> Self {
core::ptr::read(bytes.as_ptr() as *const &[u8] as *const Self)
}
}
pub enum Vote {
Positive,
Negative,
Insufficient,
OffState,
}
pub mod trigger {
use super::*;
use num_traits::FromPrimitive;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum Phro {
Press = 1,
Hold = 2,
Release = 3,
Off = 0,
Passthrough = 8,
}
impl Phro {
pub fn from_state(prev_state: bool, cur_state: bool) -> Self {
if !prev_state && cur_state {
Phro::Press
} else if prev_state && cur_state {
Phro::Hold
} else if prev_state && !cur_state {
Phro::Release
} else {
Phro::Off
}
}
pub fn compare(&self, cond_time: u32, event_state: Self, event_time: u32) -> Vote {
if *self != event_state {
if *self == Phro::Off {
return Vote::OffState;
} else {
return Vote::Insufficient;
}
}
match self {
Phro::Press => {
if event_time >= cond_time {
Vote::Positive
} else {
Vote::Negative
}
}
Phro::Hold => {
if event_time >= cond_time {
Vote::Positive
} else {
Vote::Insufficient
}
}
Phro::Release => {
if event_time <= cond_time {
Vote::Positive
} else {
Vote::Negative
}
}
Phro::Off => {
if event_time >= cond_time {
Vote::Positive
} else {
Vote::Negative
}
}
_ => Vote::Insufficient,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum Aodo {
Activate = 1,
On = 2,
Deactivate = 3,
Off = 0,
Passthrough = 8,
}
impl Aodo {
pub fn from_state(prev_state: bool, cur_state: bool) -> Self {
if !prev_state && cur_state {
Aodo::Activate
} else if prev_state && cur_state {
Aodo::On
} else if prev_state && !cur_state {
Aodo::Deactivate
} else {
Aodo::Off
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum Dro {
Off = 0,
Done = 1,
Repeat = 3,
Passthrough = 8,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Primitive)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum LayerState {
ShiftActivate = 0x11,
LatchActivate = 0x21,
ShiftLatchActivate = 0x31,
LockActivate = 0x41,
ShiftLockActivate = 0x51,
LatchLockActivate = 0x61,
ShiftLatchLockActivate = 0x71,
ShiftOn = 0x12,
LatchOn = 0x22,
ShiftLatchOn = 0x32,
LockOn = 0x42,
ShiftLockOn = 0x52,
LatchLockOn = 0x62,
ShiftLatchLockOn = 0x72,
ShiftDeactivate = 0x13,
LatchDeactivate = 0x23,
ShiftLatchDeactivate = 0x33,
LockDeactivate = 0x43,
ShiftLockDeactivate = 0x53,
LatchLockDeactivate = 0x63,
ShiftLatchLockDeactivate = 0x73,
ShiftOff = 0x10,
LatchOff = 0x20,
ShiftLatchOff = 0x30,
LockOff = 0x40,
ShiftLockOff = 0x50,
LatchLockOff = 0x60,
ShiftLatchLockOff = 0x70,
Passthrough = 0x08,
}
impl LayerState {
pub fn from_layer(layer_state: layer::State, activity_state: Aodo) -> Self {
LayerState::from_u32(((layer_state as u32) << 1) | activity_state as u32).unwrap()
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum TriggerEvent {
None = 0,
Switch {
state: trigger::Phro,
index: u16,
last_state: u32,
} = 1,
HidLed {
state: trigger::Aodo,
index: u8,
last_state: u32,
} = 2,
AnalogDistance {
index: u16,
val: i16,
} = 3,
AnalogVelocity {
index: u16,
val: i16,
} = 4,
AnalogAcceleration {
index: u16,
val: i16,
} = 5,
AnalogJerk {
index: u16,
val: i16,
} = 6,
Layer {
state: trigger::LayerState,
layer: u8,
last_state: u32,
} = 7,
Animation {
state: trigger::Dro,
index: u16,
last_state: u32,
} = 8,
Sleep {
state: trigger::Aodo,
last_state: u32,
} = 9,
Resume {
state: trigger::Aodo,
last_state: u32,
} = 10,
Inactive {
state: trigger::Aodo,
last_state: u32,
} = 11,
Active {
state: trigger::Aodo,
last_state: u32,
} = 12,
Rotation {
index: u8,
position: i8,
last_state: u32,
} = 13,
}
impl TriggerEvent {
pub const unsafe fn bytes(&self) -> &[u8] {
&*core::ptr::slice_from_raw_parts(
(self as *const Self) as *const u8,
core::mem::size_of::<Self>(),
)
}
pub const unsafe fn from_byte_array(bytes: [u8; core::mem::size_of::<Self>()]) -> Self {
core::mem::transmute(bytes)
}
pub const unsafe fn from_bytes(bytes: &[u8]) -> Self {
core::ptr::read(bytes.as_ptr() as *const &[u8] as *const Self)
}
pub fn index(&self) -> u16 {
match self {
TriggerEvent::None => 0,
TriggerEvent::Switch { index, .. } => *index,
TriggerEvent::HidLed { index, .. } => (*index).into(),
TriggerEvent::AnalogDistance { index, .. } => *index,
TriggerEvent::AnalogVelocity { index, .. } => *index,
TriggerEvent::AnalogAcceleration { index, .. } => *index,
TriggerEvent::AnalogJerk { index, .. } => *index,
TriggerEvent::Layer { layer, .. } => (*layer).into(),
TriggerEvent::Animation { index, .. } => *index,
TriggerEvent::Sleep { .. } => 0,
TriggerEvent::Resume { .. } => 0,
TriggerEvent::Inactive { .. } => 0,
TriggerEvent::Active { .. } => 0,
TriggerEvent::Rotation { index, .. } => (*index).into(),
}
}
}
const_assert_eq!(core::mem::size_of::<TriggerEvent>(), 8);
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum TriggerCondition {
None = 0,
Switch {
state: trigger::Phro,
index: u16,
loop_condition_index: u16,
} = 1,
HidLed {
state: trigger::Aodo,
loop_condition_index: u16,
index: u8,
} = 2,
AnalogDistance {
reserved: u8,
index: u16,
val: i16,
} = 3,
AnalogVelocity {
reserved: u8,
index: u16,
val: i16,
} = 4,
AnalogAcceleration {
reserved: u8,
index: u16,
val: i16,
} = 5,
AnalogJerk {
reserved: u8,
index: u16,
val: i16,
} = 6,
Layer {
state: trigger::LayerState,
loop_condition_index: u16,
layer: u8,
} = 7,
Animation {
state: trigger::Dro,
index: u16,
loop_condition_index: u16,
} = 8,
Sleep {
state: trigger::Aodo,
loop_condition_index: u16,
} = 9,
Resume {
state: trigger::Aodo,
loop_condition_index: u16,
} = 10,
Inactive {
state: trigger::Aodo,
loop_condition_index: u16,
} = 11,
Active {
state: trigger::Aodo,
loop_condition_index: u16,
} = 12,
Rotation {
index: u8,
loop_condition_index: u16,
position: i8,
} = 13,
}
const_assert_eq!(core::mem::size_of::<TriggerCondition>(), 6);
impl TriggerCondition {
pub const unsafe fn bytes(&self) -> &[u8] {
&*core::ptr::slice_from_raw_parts(
(self as *const Self) as *const u8,
core::mem::size_of::<Self>(),
)
}
pub const unsafe fn from_byte_array(bytes: [u8; core::mem::size_of::<Self>()]) -> Self {
core::mem::transmute(bytes)
}
pub const unsafe fn from_bytes(bytes: &[u8]) -> Self {
core::ptr::read(bytes.as_ptr() as *const &[u8] as *const Self)
}
pub fn index(&self) -> u16 {
match self {
TriggerCondition::None => 0,
TriggerCondition::Switch { index, .. } => *index,
TriggerCondition::HidLed { index, .. } => (*index).into(),
TriggerCondition::AnalogDistance { index, .. } => *index,
TriggerCondition::AnalogVelocity { index, .. } => *index,
TriggerCondition::AnalogAcceleration { index, .. } => *index,
TriggerCondition::AnalogJerk { index, .. } => *index,
TriggerCondition::Layer { layer, .. } => (*layer).into(),
TriggerCondition::Animation { index, .. } => *index,
TriggerCondition::Sleep { .. } => 0,
TriggerCondition::Resume { .. } => 0,
TriggerCondition::Inactive { .. } => 0,
TriggerCondition::Active { .. } => 0,
TriggerCondition::Rotation { index, .. } => (*index).into(),
}
}
pub fn evaluate(&self, event: TriggerEvent, loop_condition_lookup: &[u32]) -> Vote {
if u8::from(*self) != u8::from(event) {
return Vote::Insufficient;
}
if self.index() != event.index() {
return Vote::Insufficient;
}
match self {
TriggerCondition::None => Vote::Positive,
TriggerCondition::Switch {
state,
loop_condition_index,
..
} => {
if let TriggerEvent::Switch {
state: e_state,
last_state,
..
} = event
{
state.compare(
loop_condition_lookup[*loop_condition_index as usize],
e_state,
last_state,
)
} else {
Vote::Insufficient
}
}
_ => {
panic!("Unknown condition! Please fix.");
}
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum CapabilityState {
None = 0,
Initial = 1,
Last = 2,
Any = 3,
Passthrough = 4,
}
impl CapabilityState {
pub fn event(&self, event: TriggerEvent) -> CapabilityEvent {
match self {
CapabilityState::None => CapabilityEvent::None,
CapabilityState::Initial => CapabilityEvent::Initial,
CapabilityState::Last => CapabilityEvent::Last,
CapabilityState::Any => CapabilityEvent::Any,
CapabilityState::Passthrough => CapabilityEvent::Passthrough(event),
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum CapabilityEvent {
None = 0,
Initial = 1,
Last = 2,
Any = 3,
Passthrough(TriggerEvent) = 4,
}