use heapless::Vec;
use postcard::experimental::max_size::MaxSize;
use serde::{Deserialize, Serialize};
use crate::action::KeyAction;
use crate::constants::COMBO_SIZE;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
#[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))]
pub struct Combo {
#[cfg_attr(feature = "wasm", tsify(type = "KeyAction[]"))]
pub actions: Vec<KeyAction, COMBO_SIZE>,
pub output: KeyAction,
pub layer: Option<u8>,
}
impl MaxSize for Combo {
const POSTCARD_MAX_SIZE: usize = crate::heapless_vec_max_size::<KeyAction, COMBO_SIZE>()
+ KeyAction::POSTCARD_MAX_SIZE
+ Option::<u8>::POSTCARD_MAX_SIZE;
}
impl Combo {
pub fn new<I: IntoIterator<Item = KeyAction>>(actions: I, output: KeyAction, layer: Option<u8>) -> Self {
let mut combo_actions = Vec::new();
for action in actions {
if action != KeyAction::No && combo_actions.push(action).is_err() {
break;
}
}
Self {
actions: combo_actions,
output,
layer,
}
}
pub fn empty() -> Self {
Self {
actions: Vec::new(),
output: KeyAction::No,
layer: None,
}
}
pub fn size(&self) -> usize {
self.actions.len()
}
pub fn find_key_action_index(&self, key_action: &KeyAction) -> Option<usize> {
self.actions.iter().position(|a| a == key_action)
}
pub fn contains(&self, key_action: &KeyAction) -> bool {
self.actions.contains(key_action)
}
}