diff --git a/Cargo.lock b/Cargo.lock index 6163ffd..50f445e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -323,6 +323,21 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.30" @@ -330,6 +345,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -338,6 +354,34 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures-sink" version = "0.3.30" @@ -356,10 +400,16 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ + "futures-channel", "futures-core", + "futures-io", + "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", + "slab", ] [[package]] @@ -424,6 +474,7 @@ version = "0.0.4" dependencies = [ "clap", "crossterm", + "futures", "hitt-formatter", "hitt-parser", "hitt-request", diff --git a/hitt-cli/Cargo.toml b/hitt-cli/Cargo.toml index 959edac..e2c9e68 100644 --- a/hitt-cli/Cargo.toml +++ b/hitt-cli/Cargo.toml @@ -20,6 +20,7 @@ path = "src/main.rs" [dependencies] clap = { version = "4.4.18", features = ["derive"] } crossterm = "0.27.0" +futures = "0.3.30" hitt-formatter = { workspace = true } hitt-parser = { workspace = true } hitt-request = { workspace = true } diff --git a/hitt-cli/src/commands/run.rs b/hitt-cli/src/commands/run.rs index 455d72e..60b5bc4 100644 --- a/hitt-cli/src/commands/run.rs +++ b/hitt-cli/src/commands/run.rs @@ -1,10 +1,12 @@ +use std::sync::Arc; + use crossterm::{style::Print, style::Stylize, QueueableCommand}; use hitt_request::send_request; use crate::{ config::{variables::parse_variable_argument, RunCommandArguments}, error::HittCliError, - fs::{find_http_files, parse_requests_threaded}, + fs::{find_http_files, parse_file, parse_files}, terminal::handle_response, }; @@ -20,14 +22,6 @@ pub async fn run_command( return Err(HittCliError::RecursiveNotEnabled); } - let http_file_paths = if is_dir_path { - find_http_files(&args.path) - } else { - vec![args.path.clone()] - }; - - let timeout = args.timeout.map(core::time::Duration::from_millis); - let mut vars = std::collections::HashMap::new(); if let Some(arg_variables) = args.var.clone() { @@ -38,19 +32,31 @@ pub async fn run_command( } } - let parsed_files = parse_requests_threaded(http_file_paths, vars).await?; + let parsed_files = if is_dir_path { + parse_files(find_http_files(&args.path), vars).await + } else { + parse_file(&args.path, Arc::new(vars)) + .await + .map(|r| vec![r]) + }?; + + let timeout = args.timeout.map(core::time::Duration::from_millis); let mut request_count: u16 = 0; for (path, file) in parsed_files { if !args.vim { - term.queue(Print(format!("hitt: running {path:?}\n\n").cyan()))?; + if request_count > 0 { + term.queue(Print('\n'))?; + } + + term.queue(Print(format!("hitt: running {path:?}\n").cyan()))?; term.flush()?; } for req in file { - if request_count > 0 { - term.queue(Print("\n"))?; + if !args.vim || request_count != 0 { + term.queue(Print('\n'))?; } match send_request(&http_client, &req, &timeout).await { diff --git a/hitt-cli/src/fs/mod.rs b/hitt-cli/src/fs/mod.rs index dea0179..0bc3100 100644 --- a/hitt-cli/src/fs/mod.rs +++ b/hitt-cli/src/fs/mod.rs @@ -1,17 +1,28 @@ use std::sync::Arc; +use futures::future::TryJoinAll; use hitt_parser::HittRequest; use crate::error::HittCliError; -#[inline] -async fn get_file_content(path: &std::path::Path) -> Result { - tokio::fs::read(path) - .await - .map(|buf| String::from_utf8_lossy(&buf).to_string()) +pub async fn parse_file( + path: &std::path::Path, + input_variables: Arc>, +) -> Result<(std::path::PathBuf, Vec), HittCliError> { + match tokio::fs::read(&path).await { + Ok(buf) => { + let content = String::from_utf8_lossy(&buf); + + match hitt_parser::parse_requests(&content, &input_variables) { + Ok(reqs) => Ok((path.to_owned(), reqs)), + Err(e) => Err(HittCliError::Parse(path.to_owned(), e)), + } + } + Err(err) => Err(HittCliError::IoRead(path.to_owned(), err)), + } } -pub async fn parse_requests_threaded( +pub async fn parse_files( paths: Vec, input_variables: std::collections::HashMap, ) -> Result)>, HittCliError> { @@ -22,36 +33,18 @@ pub async fn parse_requests_threaded( .map(|path| { let var_clone = Arc::clone(&vars); - tokio::task::spawn(async move { - ( - get_file_content(&path) - .await - .map(|content| { - hitt_parser::parse_requests(&content, &var_clone) - .map_err(|error| HittCliError::Parse(path.clone(), error)) - }) - .map_err(|error| HittCliError::IoRead(path.clone(), error)), - path, - ) - }) + tokio::task::spawn(async move { parse_file(&path, var_clone).await }) }) - .collect::>(); + .collect::>() + .await?; let mut parsed_requests = Vec::new(); for handle in handles { - let result = handle.await.map_err(HittCliError::Join)?; - - // TODO: clean up this mess - let reqs = result.0??; - - parsed_requests.push((reqs, result.1)); + parsed_requests.push(handle?); } - Ok(parsed_requests - .into_iter() - .map(|(reqs, path)| (path, reqs)) - .collect()) + Ok(parsed_requests) } pub fn find_http_files(path: &std::path::Path) -> Vec { diff --git a/hitt-cli/src/terminal/body.rs b/hitt-cli/src/terminal/body.rs index cef353d..cd5fffd 100644 --- a/hitt-cli/src/terminal/body.rs +++ b/hitt-cli/src/terminal/body.rs @@ -6,7 +6,7 @@ use hitt_formatter::ContentType; #[inline] fn __print_body(term: &mut W, body: &str) -> Result<(), std::io::Error> { - queue!(term, Print("\n"), Print(body.dark_yellow()), Print("\n\n")) + queue!(term, Print('\n'), Print(body.dark_yellow()), Print("\n\n")) } #[cfg(test)]