use crate::event::Event;
use alloc::vec::Vec;
use core::time::Duration;
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct InputRecording {
width: u16,
height: u16,
events: Vec<(Duration, Event)>,
}
impl InputRecording {
#[must_use]
pub const fn new(width: u16, height: u16) -> Self {
Self {
width,
height,
events: Vec::new(),
}
}
#[must_use]
pub const fn width(&self) -> u16 {
self.width
}
#[must_use]
pub const fn height(&self) -> u16 {
self.height
}
pub fn push(&mut self, delay: Duration, event: Event) {
self.events.push((delay, event));
}
#[must_use]
pub fn events(&self) -> impl ExactSizeIterator<Item = &(Duration, Event)> {
self.events.iter()
}
#[must_use]
pub const fn len(&self) -> usize {
self.events.len()
}
#[must_use]
pub const fn is_empty(&self) -> bool {
self.events.is_empty()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::event::{KeyCode, KeyEvent, KeyModifiers};
#[test]
fn new_recording_is_empty() {
let recording = InputRecording::new(80, 24);
assert_eq!(recording.width(), 80);
assert_eq!(recording.height(), 24);
assert!(recording.is_empty());
assert_eq!(recording.len(), 0);
}
#[test]
fn push_appends_in_order() {
let mut recording = InputRecording::new(4, 2);
let a = Event::Key(KeyEvent::new(KeyCode::Char('a'), KeyModifiers::NONE));
let b = Event::Key(KeyEvent::new(KeyCode::Char('b'), KeyModifiers::NONE));
recording.push(Duration::ZERO, a.clone());
recording.push(Duration::from_millis(50), b.clone());
let events: Vec<_> = recording.events().collect();
assert_eq!(
events,
vec![&(Duration::ZERO, a), &(Duration::from_millis(50), b)]
);
assert_eq!(recording.len(), 2);
assert!(!recording.is_empty());
}
#[cfg(feature = "serde")]
#[test]
fn round_trips_through_serde_json() {
let mut recording = InputRecording::new(80, 24);
recording.push(
Duration::ZERO,
Event::Key(KeyEvent::new(KeyCode::Char('a'), KeyModifiers::NONE)),
);
recording.push(
Duration::from_millis(250),
Event::Key(KeyEvent::new(KeyCode::Enter, KeyModifiers::SHIFT)),
);
let json = serde_json::to_string(&recording).expect("serialize");
let round_tripped: InputRecording = serde_json::from_str(&json).expect("deserialize");
assert_eq!(round_tripped, recording);
}
}