use std::io::{self, Stdout, Write};
use anyhow::{Context, Result};
use crossterm::{
event::{DisableMouseCapture, EnableMouseCapture},
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
#[must_use = "dropping this guard disables raw mode immediately"]
pub struct RawModeGuard {
_private: (),
}
impl RawModeGuard {
pub fn enter() -> Result<Self> {
enable_raw_mode().context("enable raw mode")?;
Ok(Self { _private: () })
}
}
impl Drop for RawModeGuard {
fn drop(&mut self) {
let _ = disable_raw_mode();
}
}
#[must_use = "dropping this guard leaves the alternate screen immediately"]
pub struct AltScreenGuard {
stdout: Stdout,
}
impl AltScreenGuard {
pub fn enter() -> Result<Self> {
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen).context("enter alt screen")?;
Ok(Self { stdout })
}
}
impl Drop for AltScreenGuard {
fn drop(&mut self) {
let _ = execute!(self.stdout, LeaveAlternateScreen);
let _ = self.stdout.flush();
}
}
#[must_use = "dropping this guard disables mouse capture immediately"]
pub struct MouseCaptureGuard {
stdout: Stdout,
}
impl MouseCaptureGuard {
pub fn enable() -> Result<Self> {
let mut stdout = io::stdout();
execute!(stdout, EnableMouseCapture).context("enable mouse capture")?;
Ok(Self { stdout })
}
}
impl Drop for MouseCaptureGuard {
fn drop(&mut self) {
let _ = execute!(self.stdout, DisableMouseCapture);
let _ = self.stdout.flush();
}
}