use std::io::{self, Stdout};
use ratatui::backend::CrosstermBackend;
use ratatui::crossterm::{
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use ratatui::Terminal;
pub type Tui = Terminal<CrosstermBackend<Stdout>>;
pub struct TerminalGuard {
pub terminal: Tui,
}
impl TerminalGuard {
pub fn new() -> io::Result<Self> {
install_panic_hook();
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen)?;
let terminal = Terminal::new(CrosstermBackend::new(stdout))?;
Ok(Self { terminal })
}
pub fn suspend(&mut self) -> io::Result<()> {
restore()
}
pub fn resume(&mut self) -> io::Result<()> {
enable_raw_mode()?;
execute!(io::stdout(), EnterAlternateScreen)?;
self.terminal.clear()?;
Ok(())
}
}
impl Drop for TerminalGuard {
fn drop(&mut self) {
let _ = restore();
}
}
fn restore() -> io::Result<()> {
disable_raw_mode()?;
execute!(io::stdout(), LeaveAlternateScreen)?;
Ok(())
}
fn install_panic_hook() {
let previous = std::panic::take_hook();
std::panic::set_hook(Box::new(move |info| {
let _ = restore();
previous(info);
}));
}