1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//! Control Utilities
//!
//! This module provides functions for controlling the console, including flushing the output buffer,
//! clearing lines, and moving the cursor in various directions.
use std::io::{self, Write};

/// Flushes the output buffer, ensuring that all content is written to the console.
pub fn flush() {
    io::stdout().flush().unwrap();
}

/// Clears the current line in the console.
///
/// This function uses ANSI escape codes to clear the entire line and move the cursor to the
/// beginning of the line.
pub fn clear_line() {
    print!("\r\x1b[2K");
    flush();
}

/// Clears the `i` lines in the console.
pub fn clear_lines(i: usize) {
    for _ in 0..i {
        print!("\r\x1b[2K");
        flush();
    }
}

/// Struct for ensuring and changing cursor visibility.
pub struct Visibility;

impl Visibility {
    /// Hide the cursor via an ASCII escape sequence.
    pub fn hide_cursor() {
        print!("\x1B[?25l");
        flush();
    }

    /// Show the cursor via an ASCII escape sequence.
    pub fn show_cursor() {
        print!("\x1B[?25h");
        flush();
    }
}

impl Drop for Visibility {
    fn drop(&mut self) {
        Visibility::show_cursor();
    }
}

/// Moves the cursor down by the specified number of lines.
///
/// # Arguments
///
/// * `n` - The number of lines to move the cursor down.
pub fn move_cursor_down(n: usize) {
    if n > 0 {
        print!("\x1b[{}B", n);
        flush();
    }
}

/// Moves the cursor up by the specified number of lines.
///
/// # Arguments
///
/// * `n` - The number of lines to move the cursor up.
pub fn move_cursor_up(n: usize) {
    if n > 0 {
        print!("\x1b[{}A", n);
        flush();
    }
}

/// Moves the cursor to the left by the specified number of characters.
///
/// # Arguments
///
/// * `n` - The number of characters to move the cursor to the left.
pub fn move_cursor_left(n: usize) {
    if n > 0 {
        print!("\x1b[{}D", n);
        flush();
    }
}

/// Moves the cursor to the right by the specified number of characters.
///
/// # Arguments
///
/// * `n` - The number of characters to move the cursor to the right.
pub fn move_cursor_right(n: usize) {
    if n > 0 {
        print!("\x1b[{}C", n);
        flush();
    }
}

/// Moves the cursor to the specified position on the console.
///
/// # Arguments
///
/// * `x` - The horizontal position (column) to move the cursor to.
/// * `y` - The vertical position (row) to move the cursor to.
pub fn move_cursor_to(x: usize, y: usize) {
    print!("\x1B[{};{}H", y + 1, x + 1);
    flush();
}