#[cfg(target_os = "linux")]
use crate::DirectToAnsiInputDevice;
use crate::{CrosstermEventResult, CrosstermInputDevice, InlineVec, InputEvent,
MockInputDevice, TERMINAL_LIB_BACKEND, TerminalLibBackend};
use std::time::Duration;
#[derive(Debug)]
#[allow(clippy::large_enum_variant)]
pub enum InputDevice {
Crossterm(CrosstermInputDevice),
#[cfg(target_os = "linux")]
DirectToAnsi(DirectToAnsiInputDevice),
Mock(MockInputDevice),
}
impl InputDevice {
#[must_use]
pub fn new() -> Self {
match TERMINAL_LIB_BACKEND {
TerminalLibBackend::Crossterm => Self::new_crossterm(),
#[cfg(target_os = "linux")]
TerminalLibBackend::DirectToAnsi => Self::new_direct_to_ansi(),
#[cfg(not(target_os = "linux"))]
TerminalLibBackend::DirectToAnsi => {
Self::new_crossterm()
}
}
}
#[must_use]
pub fn new_crossterm() -> Self {
Self::Crossterm(CrosstermInputDevice::new_event_stream())
}
#[cfg(target_os = "linux")]
#[must_use]
pub fn new_direct_to_ansi() -> Self {
Self::DirectToAnsi(DirectToAnsiInputDevice::new())
}
#[must_use]
pub fn new_mock(generator_vec: InlineVec<CrosstermEventResult>) -> Self {
Self::Mock(MockInputDevice::new(generator_vec))
}
#[must_use]
pub fn new_mock_with_delay(
generator_vec: InlineVec<CrosstermEventResult>,
delay: Duration,
) -> Self {
Self::Mock(MockInputDevice::new_with_delay(generator_vec, delay))
}
pub async fn next(&mut self) -> Option<InputEvent> {
match self {
Self::Crossterm(device) => device.next().await,
#[cfg(target_os = "linux")]
Self::DirectToAnsi(device) => device.next().await,
Self::Mock(device) => device.next().await,
}
}
#[must_use]
pub fn is_mock(&self) -> bool { matches!(self, Self::Mock(_)) }
}
impl Default for InputDevice {
fn default() -> Self { Self::new() }
}