use super::TerminalImpl;
use crossterm::event::{self, EventStream};
use futures::{StreamExt, stream::BoxStream};
use ratatui::{Frame, TerminalOptions};
use std::io::{self};
pub struct CrossTerminal {
terminal: ratatui::DefaultTerminal,
}
impl CrossTerminal {
pub fn new() -> io::Result<Self> {
Ok(Self {
terminal: ratatui::init(),
})
}
pub fn with_options(options: TerminalOptions) -> io::Result<Self> {
Ok(Self {
terminal: ratatui::init_with_options(options),
})
}
}
impl TerminalImpl for CrossTerminal {
type Event = event::Event;
fn event_stream(&mut self) -> io::Result<BoxStream<'static, Self::Event>> {
Ok(EventStream::new()
.filter_map(|event| async move { event.ok() })
.boxed())
}
fn received_ctrl_c(event: Self::Event) -> bool {
matches!(
event,
event::Event::Key(event::KeyEvent {
code: event::KeyCode::Char('c'),
modifiers: event::KeyModifiers::CONTROL,
kind: event::KeyEventKind::Press,
..
})
)
}
fn draw<F>(&mut self, f: F) -> io::Result<()>
where
F: FnOnce(&mut Frame),
{
self.terminal.draw(f)?;
Ok(())
}
fn insert_before<F>(&mut self, height: u16, draw_fn: F) -> io::Result<()>
where
F: FnOnce(&mut ratatui::prelude::Buffer),
{
self.terminal.insert_before(height, draw_fn)?;
Ok(())
}
}