use crossterm::event::Event;
use futures::StreamExt as _;
pub struct Stdin {
events: tokio::sync::mpsc::UnboundedReceiver<Event>,
reader: tokio::task::JoinHandle<()>,
}
impl Stdin {
pub fn open() -> anyhow::Result<Self> {
bitrouter_tui::lifecycle::enter_raw()?;
if let Err(e) =
crossterm::execute!(std::io::stdout(), crossterm::event::EnableBracketedPaste)
{
bitrouter_tui::lifecycle::restore();
return Err(e.into());
}
let (tx, events) = tokio::sync::mpsc::unbounded_channel();
let reader = tokio::spawn(async move {
let mut stream = crossterm::event::EventStream::new();
while let Some(Ok(event)) = stream.next().await {
if tx.send(event).is_err() {
break;
}
}
});
Ok(Self { events, reader })
}
pub async fn next_event(&mut self) -> Option<Event> {
self.events.recv().await
}
}
impl Drop for Stdin {
fn drop(&mut self) {
self.reader.abort();
bitrouter_tui::lifecycle::restore();
}
}