use std::io::{self, Stdout};
use crossterm::{
execute,
terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode},
};
use getset::MutGetters;
use ratatui::{Terminal, backend::CrosstermBackend};
use crate::error::Result;
pub type Tui = Terminal<CrosstermBackend<Stdout>>;
#[derive(MutGetters)]
pub struct TerminalGuard {
#[getset(get_mut = "pub")]
terminal: Tui,
}
impl TerminalGuard {
pub fn new() -> Result<Self> {
enable_raw_mode()?;
let mut stdout = io::stdout();
if let Err(error) = execute!(stdout, EnterAlternateScreen) {
let _ = disable_raw_mode();
return Err(error.into());
}
match Terminal::new(CrosstermBackend::new(stdout)) {
Ok(terminal) => Ok(Self { terminal }),
Err(error) => {
let _ = Self::restore();
Err(error.into())
},
}
}
pub fn restore() -> io::Result<()> {
let raw = disable_raw_mode();
let screen = execute!(io::stdout(), LeaveAlternateScreen);
raw.and(screen)
}
}
impl Drop for TerminalGuard {
fn drop(&mut self) {
let _ = Self::restore();
}
}