diff options
| author | UMTS at Teleco <crt@teleco.ch> | 2026-03-08 07:30:34 +0100 |
|---|---|---|
| committer | UMTS at Teleco <crt@teleco.ch> | 2026-03-08 07:30:34 +0100 |
| commit | 8623ef0ee74ff48a5ee24ee032f5b549f662f09d (patch) | |
| tree | 7f11543d05cfe0e7bd5aaca31ff1d4c86a271fd0 /src/output.rs | |
goofy ah
Diffstat (limited to 'src/output.rs')
| -rw-r--r-- | src/output.rs | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/src/output.rs b/src/output.rs new file mode 100644 index 0000000..fe3b141 --- /dev/null +++ b/src/output.rs @@ -0,0 +1,209 @@ +use crate::types::{DomainResult, DomainStatus, ErrorKind}; +use colored::*; +use std::io::Write; +use std::path::PathBuf; + +pub fn print_available_table(results: &[DomainResult], no_color: bool, no_unicode: bool) { + let available: Vec<&DomainResult> = results.iter().filter(|r| r.is_available()).collect(); + + if available.is_empty() { + println!("No available domains found."); + return; + } + + let max_len = available.iter().map(|r| r.full.len()).max().unwrap_or(20); + let width = max_len + 4; // padding + + let title = "Available Domains"; + let title_padded = format!("{:^width$}", title, width = width); + + if no_unicode { + // ASCII box + let border = format!("+{}+", "-".repeat(width)); + println!("{}", border); + if no_color { + println!("|{}|", title_padded); + } else { + println!("|{}|", title_padded.green()); + } + println!("+{}+", "-".repeat(width)); + for r in &available { + println!("| {:<pad$} |", r.full, pad = width - 2); + } + println!("{}", border); + } else { + // Unicode box + let top = format!("┌{}┐", "─".repeat(width)); + let sep = format!("├{}┤", "─".repeat(width)); + let bot = format!("└{}┘", "─".repeat(width)); + println!("{}", top); + if no_color { + println!("│{}│", title_padded); + } else { + println!("│{}│", title_padded.green()); + } + println!("{}", sep); + for r in &available { + println!("│ {:<pad$} │", r.full, pad = width - 2); + } + println!("{}", bot); + } +} + +pub fn print_full_table(results: &[DomainResult], no_color: bool, no_unicode: bool) { + if results.is_empty() { + println!("No results."); + return; + } + + // calc column widths + let domain_w = results.iter().map(|r| r.full.len()).max().unwrap_or(10).max(7); + let status_w = 10; // "registered" is the longest + let note_w = results.iter().map(|r| r.note_str().len()).max().unwrap_or(4).max(4); + + let domain_col = domain_w + 2; + let status_col = status_w + 2; + let note_col = note_w + 2; + + if no_unicode { + print_full_table_ascii(results, domain_col, status_col, note_col, no_color); + } else { + print_full_table_unicode(results, domain_col, status_col, note_col, no_color); + } +} + +fn print_full_table_unicode( + results: &[DomainResult], + dc: usize, + sc: usize, + nc: usize, + no_color: bool, +) { + let top = format!("┌{}┬{}┬{}┐", "─".repeat(dc), "─".repeat(sc), "─".repeat(nc)); + let sep = format!("├{}┼{}┼{}┤", "─".repeat(dc), "─".repeat(sc), "─".repeat(nc)); + let bot = format!("└{}┴{}┴{}┘", "─".repeat(dc), "─".repeat(sc), "─".repeat(nc)); + + println!("{}", top); + println!( + "│{:^dc$}│{:^sc$}│{:^nc$}│", + "Domains", + "Status", + "Note", + dc = dc, + sc = sc, + nc = nc, + ); + println!("{}", sep); + + for r in results { + let domain_str = format!(" {:<width$} ", r.full, width = dc - 2); + let status_str = format!(" {:<width$} ", r.status_str(), width = sc - 2); + let note_str = format!(" {:<width$} ", r.note_str(), width = nc - 2); + + if no_color { + println!("│{}│{}│{}│", domain_str, status_str, note_str); + } else { + let colored_domain = color_domain(&domain_str, &r.status); + println!("│{}│{}│{}│", colored_domain, status_str, note_str); + } + } + + println!("{}", bot); +} + +fn print_full_table_ascii( + results: &[DomainResult], + dc: usize, + sc: usize, + nc: usize, + no_color: bool, +) { + let border = format!("+{}+{}+{}+", "-".repeat(dc), "-".repeat(sc), "-".repeat(nc)); + + println!("{}", border); + println!( + "|{:^dc$}|{:^sc$}|{:^nc$}|", + "Domains", + "Status", + "Note", + dc = dc, + sc = sc, + nc = nc, + ); + println!("{}", border); + + for r in results { + let domain_str = format!(" {:<width$} ", r.full, width = dc - 2); + let status_str = format!(" {:<width$} ", r.status_str(), width = sc - 2); + let note_str = format!(" {:<width$} ", r.note_str(), width = nc - 2); + + if no_color { + println!("|{}|{}|{}|", domain_str, status_str, note_str); + } else { + let colored_domain = color_domain(&domain_str, &r.status); + println!("|{}|{}|{}|", colored_domain, status_str, note_str); + } + } + + println!("{}", border); +} + +fn color_domain(domain: &str, status: &DomainStatus) -> ColoredString { + match status { + DomainStatus::Available => domain.green(), + DomainStatus::Registered { .. } => domain.red(), + DomainStatus::Error { kind, .. } => match kind { + ErrorKind::InvalidTld => domain.yellow(), + _ => domain.blue(), + }, + } +} + +pub fn print_csv(results: &[DomainResult]) { + println!("Domains, Status, Note"); + for r in results { + println!("{}, {}, {}", r.full, r.status_str(), r.note_str()); + } +} + +pub fn write_csv_file(results: &[DomainResult], path: &PathBuf) -> Result<(), String> { + let mut file = std::fs::File::create(path) + .map_err(|e| format!("Could not create CSV file: {}", e))?; + writeln!(file, "Domains, Status, Note") + .map_err(|e| format!("Write error: {}", e))?; + for r in results { + writeln!(file, "{}, {}, {}", r.full, r.status_str(), r.note_str()) + .map_err(|e| format!("Write error: {}", e))?; + } + Ok(()) +} + +pub fn print_errors(results: &[DomainResult], verbose: bool) { + for r in results { + if let DomainStatus::Error { kind, message } = &r.status { + match kind { + ErrorKind::InvalidTld => { + eprintln!("Error for {}, tld does not seem to exist", r.full); + } + _ => { + if verbose { + eprintln!("Error for {}, {} (raw: {})", r.full, message, message); + } else { + eprintln!( + "Error for {}, unknown error (enable verbose to see raw error)", + r.full + ); + } + } + } + } + } +} + +pub fn print_progress(current: usize, total: usize) { + let percent = (current as f64 / total as f64 * 100.0) as u32; + eprint!("\rParsing results : {}%", percent); + if current == total { + eprintln!("\rParsing results : Done "); + } +} |
