use std::io::{self, Write};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Cursor;
impl Cursor {
pub fn up<W: Write>(writer: &mut W, n: u16) -> io::Result<()> {
write!(writer, "\x1b[{n}A")
}
pub fn down<W: Write>(writer: &mut W, n: u16) -> io::Result<()> {
write!(writer, "\x1b[{n}B")
}
pub fn right<W: Write>(writer: &mut W, n: u16) -> io::Result<()> {
write!(writer, "\x1b[{n}C")
}
pub fn left<W: Write>(writer: &mut W, n: u16) -> io::Result<()> {
write!(writer, "\x1b[{n}D")
}
pub fn set_position<W: Write>(writer: &mut W, x: u16, y: u16) -> io::Result<()> {
write!(writer, "\x1b[{y};{x}H")
}
pub fn hide<W: Write>(writer: &mut W) -> io::Result<()> {
writer.write_all(b"\x1b[?25l")
}
pub fn show<W: Write>(writer: &mut W) -> io::Result<()> {
writer.write_all(b"\x1b[?25h")
}
pub fn save_position<W: Write>(writer: &mut W) -> io::Result<()> {
writer.write_all(b"\x1b[s")
}
pub fn restore_position<W: Write>(writer: &mut W) -> io::Result<()> {
writer.write_all(b"\x1b[u")
}
pub fn flush<W: Write>(writer: &mut W) -> io::Result<()> {
writer.flush()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cursor_movements_generate_correct_ansi() -> Result<(), Box<dyn std::error::Error>> {
let mut buffer = Vec::new();
Cursor::set_position(&mut buffer, 10, 5)?;
assert_eq!(buffer, b"\x1b[5;10H");
buffer.clear();
Cursor::up(&mut buffer, 2)?;
assert_eq!(buffer, b"\x1b[2A");
Ok(())
}
}