use std::{collections::VecDeque, time::Duration};
use crate::{Event, RecordError, RecordInput, TerminalKind};
pub fn make_binary_description(hash: &str, num_bytes: u64) -> String {
format!("{} ({} bytes)", hash, num_bytes)
}
pub struct CrosstermInput;
impl RecordInput for CrosstermInput {
fn terminal_kind(&self) -> TerminalKind {
TerminalKind::Crossterm
}
fn next_events(&mut self) -> Result<Vec<Event>, RecordError> {
let first_event = crossterm::event::read().map_err(RecordError::ReadInput)?;
let mut events = vec![first_event.into()];
while crossterm::event::poll(Duration::ZERO).map_err(RecordError::ReadInput)? {
let event = crossterm::event::read().map_err(RecordError::ReadInput)?;
events.push(event.into());
}
Ok(events)
}
fn edit_commit_message(&mut self, message: &str) -> Result<String, RecordError> {
Ok(message.to_owned())
}
}
pub struct TestingInput {
pub width: usize,
pub height: usize,
pub events: Box<dyn Iterator<Item = Event>>,
pub commit_messages: VecDeque<String>,
}
impl TestingInput {
pub fn new(
width: usize,
height: usize,
events: impl IntoIterator<Item = Event> + 'static,
) -> Self {
Self {
width,
height,
events: Box::new(events.into_iter()),
commit_messages: Default::default(),
}
}
}
impl RecordInput for TestingInput {
fn terminal_kind(&self) -> TerminalKind {
let Self {
width,
height,
events: _,
commit_messages: _,
} = self;
TerminalKind::Testing {
width: *width,
height: *height,
}
}
fn next_events(&mut self) -> Result<Vec<Event>, RecordError> {
Ok(vec![self.events.next().unwrap_or(Event::None)])
}
fn edit_commit_message(&mut self, _message: &str) -> Result<String, RecordError> {
self.commit_messages
.pop_front()
.ok_or_else(|| RecordError::Other("No more commit messages available".to_string()))
}
}