use std::{collections::VecDeque, time::Duration};
use crate::{Event, RecordError, RecordInput, TerminalKind};
pub fn make_binary_description(hash: &str, num_bytes: u64) -> String {
format!("{hash} ({num_bytes} 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(|err| RecordError::ReadInput(err.into()))?;
let mut events = vec![first_event.into()];
while crossterm::event::poll(Duration::ZERO)
.map_err(|err| RecordError::ReadInput(err.into()))?
{
let event =
crossterm::event::read().map_err(|err| RecordError::ReadInput(err.into()))?;
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()))
}
}