From 6ae3a074e9e2ee0cb5e9da4581f3bea27d873d77 Mon Sep 17 00:00:00 2001 From: Mads Hougesen Date: Sat, 23 Dec 2023 17:13:52 +0100 Subject: [PATCH] refactor: use console::Term instead of println (#38) --- examples/get-request.http | 2 +- hitt-cli/src/commands/new.rs | 18 ++++++++++-------- hitt-cli/src/commands/run.rs | 16 ++++++++++------ hitt-cli/src/config/mod.rs | 3 +++ hitt-cli/src/main.rs | 10 +++++++--- hitt-cli/src/terminal/body.rs | 22 +++++++++++++--------- hitt-cli/src/terminal/headers.rs | 15 ++++++++++++--- hitt-cli/src/terminal/mod.rs | 18 +++++++++++++----- hitt-cli/src/terminal/status.rs | 7 +++++-- hitt-parser/src/lib.rs | 4 +--- 10 files changed, 75 insertions(+), 40 deletions(-) diff --git a/examples/get-request.http b/examples/get-request.http index 72737c3..f9bc8c0 100644 --- a/examples/get-request.http +++ b/examples/get-request.http @@ -1 +1 @@ -GET https://mhouge.dk +GET https://api.goout.dk diff --git a/hitt-cli/src/commands/new.rs b/hitt-cli/src/commands/new.rs index 09ccb0a..d87fbf3 100644 --- a/hitt-cli/src/commands/new.rs +++ b/hitt-cli/src/commands/new.rs @@ -125,6 +125,7 @@ async fn check_if_exist(term: &Term, path: &std::path::Path) -> Result<(), std:: )?; if !should_continue { + term.flush()?; std::process::exit(0); } } @@ -132,18 +133,19 @@ async fn check_if_exist(term: &Term, path: &std::path::Path) -> Result<(), std:: Ok(()) } -pub(crate) async fn new_command(args: &NewCommandArguments) -> Result<(), HittCliError> { - let term = console::Term::stdout(); - - check_if_exist(&term, &args.path).await?; +pub(crate) async fn new_command( + term: &console::Term, + args: &NewCommandArguments, +) -> Result<(), HittCliError> { + check_if_exist(term, &args.path).await?; - let method = set_method(&term)?; + let method = set_method(term)?; - let url = set_url(&term)?; + let url = set_url(term)?; - let headers = set_headers(&term)?; + let headers = set_headers(term)?; - let body = set_body(&term, try_find_content_type(&headers))?; + let body = set_body(term, try_find_content_type(&headers))?; save_request(&args.path, method, url, &headers, body) } diff --git a/hitt-cli/src/commands/run.rs b/hitt-cli/src/commands/run.rs index 484bef6..681c777 100644 --- a/hitt-cli/src/commands/run.rs +++ b/hitt-cli/src/commands/run.rs @@ -7,7 +7,10 @@ use crate::{ terminal::handle_response, }; -pub(crate) async fn run_command(args: &RunCommandArguments) -> Result<(), HittCliError> { +pub(crate) async fn run_command( + term: &console::Term, + args: &RunCommandArguments, +) -> Result<(), HittCliError> { let http_client = reqwest::Client::new(); let http_file_paths = match std::fs::metadata(&args.path).map(|metadata| metadata.is_dir())? { @@ -18,14 +21,13 @@ pub(crate) async fn run_command(args: &RunCommandArguments) -> Result<(), HittCl let parsed_files = parse_requests_threaded(http_file_paths).await?; for (path, file) in parsed_files { - println!("hitt: running {:?}", path); + if !args.vim { + term.write_line(&format!("hitt: running {:?}", path))?; + } for req in file { match send_request(&http_client, &req).await { - Ok(response) => { - handle_response(response, args); - Ok(()) - } + Ok(response) => handle_response(term, response, args), Err(request_error) => { Err(HittCliError::Reqwest(req.method, req.uri, request_error)) } @@ -33,5 +35,7 @@ pub(crate) async fn run_command(args: &RunCommandArguments) -> Result<(), HittCl } } + term.flush()?; + Ok(()) } diff --git a/hitt-cli/src/config/mod.rs b/hitt-cli/src/config/mod.rs index 25d2598..ecf92a5 100644 --- a/hitt-cli/src/config/mod.rs +++ b/hitt-cli/src/config/mod.rs @@ -40,6 +40,9 @@ pub(crate) struct RunCommandArguments { /// Enable to run directory recursively #[arg(long, short, default_value_t = false)] pub(crate) recursive: bool, + + #[arg(long, default_value_t = false)] + pub(crate) vim: bool, } /// Create new http request diff --git a/hitt-cli/src/main.rs b/hitt-cli/src/main.rs index 522d99c..1639ecf 100644 --- a/hitt-cli/src/main.rs +++ b/hitt-cli/src/main.rs @@ -16,14 +16,18 @@ mod terminal; async fn main() -> Result<(), HittCliError> { let cli = Cli::parse(); + let term = console::Term::stdout(); + let command_result = match &cli.command { - Commands::Run(args) => run_command(args).await, - Commands::New(args) => new_command(args).await, + Commands::Run(args) => run_command(&term, args).await, + Commands::New(args) => new_command(&term, args).await, }; if let Err(err) = command_result { - eprintln!("{}", err); + term.write_line(&err.to_string())?; } + term.flush()?; + Ok(()) } diff --git a/hitt-cli/src/terminal/body.rs b/hitt-cli/src/terminal/body.rs index acf6369..c917e8f 100644 --- a/hitt-cli/src/terminal/body.rs +++ b/hitt-cli/src/terminal/body.rs @@ -3,28 +3,32 @@ use hitt_formatter::ContentType; use crate::terminal::{TEXT_RESET, TEXT_YELLOW}; #[inline] -fn __print_body(body: &str) { - println!("\n{TEXT_YELLOW}{body}{TEXT_RESET}") +fn __print_body(term: &console::Term, body: &str) -> Result<(), std::io::Error> { + term.write_line(&format!("\n{TEXT_YELLOW}{body}{TEXT_RESET}")) } #[inline] -pub(crate) fn print_body(body: &str, content_type: Option<&str>, disable_pretty_printing: bool) { +pub(crate) fn print_body( + term: &console::Term, + body: &str, + content_type: Option<&str>, + disable_pretty_printing: bool, +) -> Result<(), std::io::Error> { if disable_pretty_printing { - __print_body(body); - return; + return __print_body(term, body); } match content_type { Some(content_type) => match ContentType::from(content_type) { - ContentType::Unknown => __print_body(body), + ContentType::Unknown => __print_body(term, body), i => { if let Some(formatted) = hitt_formatter::format(body, i) { - __print_body(&formatted) + __print_body(term, &formatted) } else { - __print_body(body) + __print_body(term, body) } } }, - None => __print_body(body), + None => __print_body(term, body), } } diff --git a/hitt-cli/src/terminal/headers.rs b/hitt-cli/src/terminal/headers.rs index 6164f8b..d91216c 100644 --- a/hitt-cli/src/terminal/headers.rs +++ b/hitt-cli/src/terminal/headers.rs @@ -1,12 +1,21 @@ use crate::terminal::{TEXT_RED, TEXT_RESET, TEXT_YELLOW}; #[inline] -pub(crate) fn print_headers(headers: &reqwest::header::HeaderMap) { +pub(crate) fn print_headers( + term: &console::Term, + headers: &reqwest::header::HeaderMap, +) -> Result<(), std::io::Error> { for (key, value) in headers { if let Ok(value) = value.to_str() { - println!("{TEXT_YELLOW}{key}{TEXT_RESET}: {value}{TEXT_RESET}"); + term.write_line(&format!( + "{TEXT_YELLOW}{key}{TEXT_RESET}: {value}{TEXT_RESET}" + ))?; } else { - eprintln!("{TEXT_RED}hitt: error printing value for header - {key}{TEXT_RESET}") + term.write_line(&format!( + "{TEXT_RED}hitt: error printing value for header - {key}{TEXT_RESET}" + ))?; } } + + Ok(()) } diff --git a/hitt-cli/src/terminal/mod.rs b/hitt-cli/src/terminal/mod.rs index 9db3052..0287a60 100644 --- a/hitt-cli/src/terminal/mod.rs +++ b/hitt-cli/src/terminal/mod.rs @@ -1,7 +1,7 @@ use console::Term; use hitt_request::HittResponse; -use crate::config::RunCommandArguments; +use crate::{config::RunCommandArguments, error::HittCliError}; use self::{body::print_body, headers::print_headers, status::print_status}; @@ -23,17 +23,22 @@ pub const TEXT_YELLOW: &str = "\x1B[33m"; pub const TEXT_RESET: &str = "\x1B[39m"; -pub(crate) fn handle_response(response: HittResponse, args: &RunCommandArguments) { +pub(crate) fn handle_response( + term: &console::Term, + response: HittResponse, + args: &RunCommandArguments, +) -> Result<(), HittCliError> { print_status( + term, &response.http_version, &response.method, &response.url, response.status_code.as_u16(), &response.duration, - ); + )?; if !args.hide_headers { - print_headers(&response.headers); + print_headers(term, &response.headers)?; } if !args.hide_body && !response.body.is_empty() { @@ -42,15 +47,18 @@ pub(crate) fn handle_response(response: HittResponse, args: &RunCommandArguments .get("content-type") .map(|x| x.to_str().expect("response content-type to be valid")); - print_body(&response.body, content_type, args.disable_formatting); + print_body(term, &response.body, content_type, args.disable_formatting)?; } if args.fail_fast && (response.status_code.is_client_error() || response.status_code.is_server_error()) { + term.flush()?; // NOTE: should the exit code be changed? std::process::exit(0); } + + Ok(()) } pub(crate) fn write_prompt(term: &Term, prompt: &str) -> Result<(), std::io::Error> { diff --git a/hitt-cli/src/terminal/status.rs b/hitt-cli/src/terminal/status.rs index f8ac15d..f0655e1 100644 --- a/hitt-cli/src/terminal/status.rs +++ b/hitt-cli/src/terminal/status.rs @@ -4,17 +4,20 @@ use crate::terminal::{STYLE_BOLD, STYLE_RESET, TEXT_GREEN, TEXT_RED, TEXT_RESET} #[inline] pub(crate) fn print_status( + term: &console::Term, http_version: &http::version::Version, method: &str, url: &str, status_code: u16, duration: &std::time::Duration, -) { +) -> Result<(), std::io::Error> { let text_color = if status_code < 400 { TEXT_GREEN } else { TEXT_RED }; - println!("{STYLE_BOLD}{text_color}{http_version:?} {method} {url} {status_code} {}ms{TEXT_RESET}{STYLE_RESET}", duration.as_millis()); + let line = format!("{STYLE_BOLD}{text_color}{http_version:?} {method} {url} {status_code} {}ms{TEXT_RESET}{STYLE_RESET}", duration.as_millis()); + + term.write_line(&line) } diff --git a/hitt-parser/src/lib.rs b/hitt-parser/src/lib.rs index 63365cb..8afcb7a 100644 --- a/hitt-parser/src/lib.rs +++ b/hitt-parser/src/lib.rs @@ -405,7 +405,7 @@ fn tokenize(buffer: &str) -> Result, RequestParseError> { let mut body_parts: Vec<&str> = Vec::new(); - for (_index, line) in buffer.lines().enumerate() { + for line in buffer.lines() { let trimmed_line = line.trim(); // check if line is comment (#) OR requests break (###) @@ -696,8 +696,6 @@ mod test_parse_requests { let parsed_requests = parse_requests(&format!("{method} {url}")).expect("request should be valid"); - println!("parsed_requests: {:#?}", parsed_requests); - assert!(parsed_requests.len() == 1); let first_request = &parsed_requests[0];