use anyhow::Result; use console::Style; use std::{ fmt::{self, Display}, sync::LazyLock, time::Duration, }; use crate::formatters::color::{BOLD_GREEN, BOLD_PINK, BOLD_YELLOW, DIM, NORMAL, color}; use crate::{formatters::get_response_formatter, options, stats::ResponseStats}; use super::StatsFormatter; struct CompactResponseStats { stats: ResponseStats, mode: options::OutputMode, } impl Display for CompactResponseStats { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let stats = &self.stats; if !stats.error_map.is_empty() { let input = if stats.error_map.len() == 1 { "input" } else { "inputs" }; color!( f, BOLD_PINK, "Issues found in {} {input}. Find details below.\n\n", stats.error_map.len() )?; } let response_formatter = get_response_formatter(&self.mode); for (source, responses) in super::sort_stat_map(&stats.error_map) { color!(f, BOLD_YELLOW, "[{}]:\n", source)?; for response in responses { writeln!( f, "{}", response_formatter.format_detailed_response(response) )?; } if let Some(suggestions) = stats.suggestion_map.get(source) { // Sort suggestions let mut sorted_suggestions: Vec<_> = suggestions.iter().collect(); sorted_suggestions.sort_by(|a, b| { let (a, b) = (a.to_string().to_lowercase(), b.to_string().to_lowercase()); human_sort::compare(&a, &b) }); writeln!(f, "\n\u{2139} Suggestions")?; for suggestion in sorted_suggestions { writeln!(f, "{suggestion}")?; } } writeln!(f)?; } color!(f, NORMAL, "🔍 {} Total", stats.total)?; // show duration (in a human readable format), e.g. 2m 30s let duration = Duration::from_secs(stats.duration_secs); color!(f, DIM, " (in {})", humantime::format_duration(duration))?; color!(f, BOLD_GREEN, " ✅ {} OK", stats.successful)?; let total_errors = stats.errors; let err_str = if total_errors == 1 { "Error" } else { "Errors" }; color!(f, BOLD_PINK, " 🚫 {} {}", total_errors, err_str)?; write_if_any(stats.unknown, "❓", "Unknown", &BOLD_PINK, f)?; write_if_any(stats.excludes, "👻", "Excluded", &BOLD_YELLOW, f)?; write_if_any(stats.timeouts, "⏳", "Timeouts", &BOLD_YELLOW, f)?; write_if_any(stats.unsupported, "⛔", "Unsupported", &BOLD_YELLOW, f)?; Ok(()) } } fn write_if_any( value: usize, symbol: &str, text: &str, style: &LazyLock