use crate::error::{CleanupError, MinusError, SetupError};
use crossterm::{cursor, execute, queue, terminal, tty::IsTty};
use std::io;
pub fn setup(stdout: &io::Stdout) -> std::result::Result<(), SetupError> {
let mut out = stdout.lock();
if out.is_tty() {
Ok(())
} else {
Err(SetupError::InvalidTerminal)
}?;
execute!(out, terminal::EnterAlternateScreen)
.map_err(|e| SetupError::AlternateScreen(e.into()))?;
terminal::enable_raw_mode().map_err(|e| SetupError::RawMode(e.into()))?;
execute!(out, cursor::Hide).map_err(|e| SetupError::HideCursor(e.into()))?;
Ok(())
}
pub fn cleanup(
mut out: impl io::Write,
es: &crate::ExitStrategy,
cleanup_screen: bool,
) -> std::result::Result<(), CleanupError> {
if cleanup_screen {
execute!(out, cursor::Show).map_err(|e| CleanupError::ShowCursor(e.into()))?;
terminal::disable_raw_mode().map_err(|e| CleanupError::DisableRawMode(e.into()))?;
execute!(out, terminal::LeaveAlternateScreen)
.map_err(|e| CleanupError::LeaveAlternateScreen(e.into()))?;
}
if *es == crate::ExitStrategy::ProcessQuit {
std::process::exit(0);
} else {
Ok(())
}
}
pub fn move_cursor(
out: &mut impl io::Write,
x: u16,
y: u16,
flush: bool,
) -> Result<(), MinusError> {
queue!(out, cursor::MoveTo(x, y))?;
if flush {
out.flush()?;
}
Ok(())
}