100 lines
3.9 KiB
Rust
100 lines
3.9 KiB
Rust
use std::io::{self, IsTerminal, Write};
|
|
use std::sync::Mutex;
|
|
|
|
pub const BANNER: [&str; 9] = [
|
|
" ░██████ ░██████ ",
|
|
" ░██ ░██ ░██ ░██ ",
|
|
"░██ ░██████ ░█████████████░██ ░███████ ░██████ ░████████ ░████████ ░███████ ░██░████ ",
|
|
"░██ ░██░██ ░██ ░██░████████░██ ░██ ░██ ░██ ░██░██ ░██░██ ░██░███ ",
|
|
"░██ ░███████░██ ░██ ░██ ░██░██ ░███████ ░██ ░██░██ ░██░█████████░██ ",
|
|
" ░██ ░██░██ ░██░██ ░██ ░██░██ ░██░██ ░██░██ ░██░██ ░██░██ ░██░██ ░██ ",
|
|
" ░██████ ░█████░█░██ ░██ ░██ ░██████ ░███████ ░█████░██░██ ░██░██ ░██ ░███████ ░██ ",
|
|
" ",
|
|
" ",
|
|
];
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct ScreenState {
|
|
pub current_ip: String,
|
|
pub tested: usize,
|
|
pub total: usize,
|
|
}
|
|
|
|
pub struct TerminalUi {
|
|
enabled: bool,
|
|
lock: Mutex<()>,
|
|
}
|
|
|
|
impl TerminalUi {
|
|
pub fn new(enabled: bool) -> Self {
|
|
Self {
|
|
enabled,
|
|
lock: Mutex::new(()),
|
|
}
|
|
}
|
|
|
|
pub fn is_enabled(&self) -> bool {
|
|
self.enabled
|
|
}
|
|
|
|
pub fn print_banner(&self) {
|
|
if !self.enabled {
|
|
return;
|
|
}
|
|
|
|
let _guard = self.lock.lock().expect("terminal mutex poisoned");
|
|
let mut stdout = io::stdout();
|
|
let _ = write!(stdout, "\x1b[2J\x1b[H\x1b[?25l");
|
|
for line in BANNER {
|
|
let _ = writeln!(stdout, "{line}");
|
|
}
|
|
let _ = writeln!(stdout, "IP: aguardando...");
|
|
let _ = writeln!(
|
|
stdout,
|
|
"Progress: [░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░] | 0.0%"
|
|
);
|
|
let _ = stdout.flush();
|
|
}
|
|
|
|
pub fn render(&self, state: &ScreenState) {
|
|
if !self.enabled {
|
|
return;
|
|
}
|
|
|
|
let _guard = self.lock.lock().expect("terminal mutex poisoned");
|
|
let mut stdout = io::stdout();
|
|
let percent = if state.total == 0 {
|
|
100.0
|
|
} else {
|
|
((state.tested as f64 / state.total as f64) * 100.0).min(100.0)
|
|
};
|
|
let bar_width = 36usize;
|
|
let filled = ((percent / 100.0) * bar_width as f64).round() as usize;
|
|
let empty = bar_width.saturating_sub(filled);
|
|
let bar = format!("{}{}", "█".repeat(filled), "░".repeat(empty));
|
|
let ip = format!("{:<15}", state.current_ip);
|
|
let percent = format!("{:>5.1}%", percent);
|
|
|
|
let _ = write!(
|
|
stdout,
|
|
"\x1b[2F\x1b[2KIP: {ip}\n\x1b[2KProgress: [{bar}] | {percent}\n"
|
|
);
|
|
let _ = stdout.flush();
|
|
}
|
|
|
|
pub fn finish(&self) {
|
|
if !self.enabled {
|
|
return;
|
|
}
|
|
|
|
let _guard = self.lock.lock().expect("terminal mutex poisoned");
|
|
let mut stdout = io::stdout();
|
|
let _ = write!(stdout, "\x1b[?25h");
|
|
let _ = stdout.flush();
|
|
}
|
|
}
|
|
|
|
pub fn stdout_is_terminal() -> bool {
|
|
io::stdout().is_terminal()
|
|
}
|