cargo_cleaner/
tui.rs

1use crossterm::event;
2use crossterm::event::Event as CrosstermEvent;
3use ratatui::prelude::CrosstermBackend;
4use std::sync::mpsc::Receiver;
5use std::time::Duration;
6
7#[derive(Clone, Debug)]
8pub enum Event {
9    Parent(CrosstermEvent),
10    AsyncUpdate,
11}
12
13pub struct Tui<'a> {
14    terminal: &'a mut ratatui::Terminal<CrosstermBackend<std::io::Stdout>>,
15    async_update_rx: Receiver<()>,
16}
17
18impl<'a> Tui<'a> {
19    pub fn new(
20        terminal: &'a mut ratatui::Terminal<CrosstermBackend<std::io::Stdout>>,
21        async_update_rx: Receiver<()>,
22    ) -> Self {
23        Self {
24            terminal,
25            async_update_rx,
26        }
27    }
28
29    pub fn draw(&mut self, f: impl FnOnce(&mut ratatui::Frame<'_>)) -> std::io::Result<()> {
30        self.terminal.draw(f)?;
31        Ok(())
32    }
33
34    pub fn read_event(&mut self) -> anyhow::Result<Event> {
35        loop {
36            if event::poll(Duration::from_micros(100))? {
37                return Ok(event::read().map(Event::Parent)?);
38            } else if self.async_update_rx.try_recv().is_ok() {
39                return Ok(Event::AsyncUpdate);
40            }
41        }
42    }
43}