From 9a8d2362ca5b6fe68449e274611e2e7ea997f7cd Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 4 Apr 2024 12:05:05 +0200 Subject: [PATCH] Add response formatter; refactor stats formatter This adds support for formatting responses in different ways. For now the options are * `plain`: No color, basic formatting * `color`: Color, indented formatting (default) * `emoji`: Fancy mode with emoji icons Fixes #546 Related to #271 --- lychee-bin/src/commands/check.rs | 62 +++++++----- lychee-bin/src/commands/mod.rs | 2 - lychee-bin/src/{ => formatters}/color.rs | 7 +- lychee-bin/src/formatters/log.rs | 53 ++++++++++ lychee-bin/src/formatters/mod.rs | 52 +++++----- lychee-bin/src/formatters/response.rs | 105 ++++++++++++++++++++ lychee-bin/src/formatters/response/color.rs | 21 ---- lychee-bin/src/formatters/response/mod.rs | 14 --- lychee-bin/src/formatters/response/raw.rs | 18 ---- lychee-bin/src/formatters/stats/compact.rs | 37 ++++--- lychee-bin/src/formatters/stats/detailed.rs | 35 ++++--- lychee-bin/src/formatters/stats/json.rs | 2 +- lychee-bin/src/formatters/stats/markdown.rs | 10 +- lychee-bin/src/formatters/stats/mod.rs | 2 +- lychee-bin/src/formatters/stats/raw.rs | 2 +- lychee-bin/src/main.rs | 43 +++----- lychee-bin/src/options.rs | 53 ++++++++-- lychee-bin/src/stats.rs | 58 +++++------ lychee-bin/tests/cli.rs | 10 +- lychee-lib/src/types/response.rs | 32 ++++-- lychee-lib/src/types/status.rs | 8 +- 21 files changed, 394 insertions(+), 232 deletions(-) rename lychee-bin/src/{ => formatters}/color.rs (82%) create mode 100644 lychee-bin/src/formatters/log.rs create mode 100644 lychee-bin/src/formatters/response.rs delete mode 100644 lychee-bin/src/formatters/response/color.rs delete mode 100644 lychee-bin/src/formatters/response/mod.rs delete mode 100644 lychee-bin/src/formatters/response/raw.rs diff --git a/lychee-bin/src/commands/check.rs b/lychee-bin/src/commands/check.rs index 92da1ad614..c678173480 100644 --- a/lychee-bin/src/commands/check.rs +++ b/lychee-bin/src/commands/check.rs @@ -15,7 +15,8 @@ use lychee_lib::{InputSource, Result}; use lychee_lib::{ResponseBody, Status}; use crate::archive::{Archive, Suggestion}; -use crate::formatters::response::ResponseFormatter; +use crate::formatters::get_response_formatter; +use crate::formatters::response::ResponseBodyFormatter; use crate::verbosity::Verbosity; use crate::{cache::Cache, stats::ResponseStats, ExitCode}; @@ -62,11 +63,13 @@ where accept, )); + let formatter = get_response_formatter(¶ms.cfg.mode); + let show_results_task = tokio::spawn(progress_bar_task( recv_resp, params.cfg.verbose, pb.clone(), - Arc::new(params.formatter), + formatter, stats, )); @@ -178,11 +181,17 @@ async fn progress_bar_task( mut recv_resp: mpsc::Receiver, verbose: Verbosity, pb: Option, - formatter: Arc>, + formatter: Box, mut stats: ResponseStats, ) -> Result<(Option, ResponseStats)> { while let Some(response) = recv_resp.recv().await { - show_progress(&mut io::stderr(), &pb, &response, &formatter, &verbose)?; + show_progress( + &mut io::stderr(), + &pb, + &response, + formatter.as_ref(), + &verbose, + )?; stats.add(response); } Ok((pb, stats)) @@ -275,10 +284,11 @@ fn show_progress( output: &mut dyn Write, progress_bar: &Option, response: &Response, - formatter: &Arc>, + formatter: &dyn ResponseBodyFormatter, verbose: &Verbosity, ) -> Result<()> { - let out = formatter.write_response(response)?; + let out = formatter.format_response(response.body()); + if let Some(pb) = progress_bar { pb.inc(1); pb.set_message(out.clone()); @@ -317,30 +327,26 @@ fn get_failed_urls(stats: &mut ResponseStats) -> Vec<(InputSource, Url)> { #[cfg(test)] mod tests { use log::info; + use lychee_lib::{CacheStatus, InputSource, Uri}; - use lychee_lib::{CacheStatus, InputSource, ResponseBody, Uri}; - - use crate::formatters; + use crate::{formatters::get_response_formatter, options}; use super::*; #[test] fn test_skip_cached_responses_in_progress_output() { let mut buf = Vec::new(); - let response = Response( + let response = Response::new( + Uri::try_from("http://127.0.0.1").unwrap(), + Status::Cached(CacheStatus::Ok(200)), InputSource::Stdin, - ResponseBody { - uri: Uri::try_from("http://127.0.0.1").unwrap(), - status: Status::Cached(CacheStatus::Ok(200)), - }, ); - let formatter: Arc> = - Arc::new(Box::new(formatters::response::Raw::new())); + let formatter = get_response_formatter(&options::ResponseFormat::Plain); show_progress( &mut buf, &None, &response, - &formatter, + formatter.as_ref(), &Verbosity::default(), ) .unwrap(); @@ -352,19 +358,23 @@ mod tests { #[test] fn test_show_cached_responses_in_progress_debug_output() { let mut buf = Vec::new(); - let response = Response( + let response = Response::new( + Uri::try_from("http://127.0.0.1").unwrap(), + Status::Cached(CacheStatus::Ok(200)), InputSource::Stdin, - ResponseBody { - uri: Uri::try_from("http://127.0.0.1").unwrap(), - status: Status::Cached(CacheStatus::Ok(200)), - }, ); - let formatter: Arc> = - Arc::new(Box::new(formatters::response::Raw::new())); - show_progress(&mut buf, &None, &response, &formatter, &Verbosity::debug()).unwrap(); + let formatter = get_response_formatter(&options::ResponseFormat::Plain); + show_progress( + &mut buf, + &None, + &response, + formatter.as_ref(), + &Verbosity::debug(), + ) + .unwrap(); assert!(!buf.is_empty()); let buf = String::from_utf8_lossy(&buf); - assert_eq!(buf, "↻ [200] http://127.0.0.1/ | Cached: OK (cached)\n"); + assert_eq!(buf, "[200] http://127.0.0.1/ | Cached: OK (cached)\n"); } } diff --git a/lychee-bin/src/commands/mod.rs b/lychee-bin/src/commands/mod.rs index 248a9a97ec..8643ad53af 100644 --- a/lychee-bin/src/commands/mod.rs +++ b/lychee-bin/src/commands/mod.rs @@ -8,7 +8,6 @@ pub(crate) use dump::dump_inputs; use std::sync::Arc; use crate::cache::Cache; -use crate::formatters::response::ResponseFormatter; use crate::options::Config; use lychee_lib::Result; use lychee_lib::{Client, Request}; @@ -18,6 +17,5 @@ pub(crate) struct CommandParams>> { pub(crate) client: Client, pub(crate) cache: Arc, pub(crate) requests: S, - pub(crate) formatter: Box, pub(crate) cfg: Config, } diff --git a/lychee-bin/src/color.rs b/lychee-bin/src/formatters/color.rs similarity index 82% rename from lychee-bin/src/color.rs rename to lychee-bin/src/formatters/color.rs index 75642b57d2..5e4951a55f 100644 --- a/lychee-bin/src/color.rs +++ b/lychee-bin/src/formatters/color.rs @@ -1,16 +1,21 @@ +//! Defines the colors used in the output of the CLI. + use console::Style; use once_cell::sync::Lazy; pub(crate) static NORMAL: Lazy