#[derive(Clone, Debug, PartialEq, Eq)]
pub enum MacroKey {
Char(char),
Esc,
Enter,
Backspace,
Tab,
Up,
Down,
Left,
Right,
Home,
End,
PageUp,
PageDown,
Delete,
Ctrl(char),
Super(char),
}
#[derive(Clone, Debug, Default)]
pub struct MacroBank {
slots: [Option<Vec<MacroKey>>; 26],
pub recording: Option<char>,
pub buffer: Vec<MacroKey>,
pub last_played: Option<char>,
}
impl MacroBank {
pub fn new() -> Self {
Self::default()
}
pub fn start(&mut self, name: char) -> bool {
if !name.is_ascii_lowercase() {
return false;
}
self.recording = Some(name);
self.buffer.clear();
true
}
pub fn stop(&mut self) {
if let Some(name) = self.recording.take() {
let idx = (name as u8 - b'a') as usize;
self.slots[idx] = Some(std::mem::take(&mut self.buffer));
}
self.buffer.clear();
}
pub fn is_recording(&self) -> bool {
self.recording.is_some()
}
pub fn push(&mut self, key: MacroKey) {
if self.recording.is_some() {
self.buffer.push(key);
}
}
pub fn get(&self, name: char) -> Option<&[MacroKey]> {
if !name.is_ascii_lowercase() {
return None;
}
let idx = (name as u8 - b'a') as usize;
self.slots[idx].as_deref()
}
pub fn set_last_played(&mut self, name: char) {
self.last_played = Some(name);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn record_and_get() {
let mut m = MacroBank::new();
assert!(m.start('a'));
m.push(MacroKey::Char('i'));
m.push(MacroKey::Char('x'));
m.push(MacroKey::Esc);
m.stop();
let keys = m.get('a').unwrap();
assert_eq!(keys.len(), 3);
}
}