diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-03-18 22:49:50 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-03-18 22:49:50 +0800 |
| commit | 5372793a49567dcba7315bf8e7bc5a1cab2d5a76 (patch) | |
| tree | 96d13d527835c23b978eae470e54a1d5fd15bc6d /src/bin | |
| parent | 2609dfe338b9bace6ff74c5efc93f684ba55a44e (diff) | |
Add support for reading from stdin and improve error messages
Diffstat (limited to 'src/bin')
| -rw-r--r-- | src/bin/jvn.rs | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/src/bin/jvn.rs b/src/bin/jvn.rs index 062eab8..fd01431 100644 --- a/src/bin/jvn.rs +++ b/src/bin/jvn.rs @@ -1,4 +1,8 @@ -use std::{ops::Deref, process::exit}; +use std::{ + ops::Deref, + path::{Path, PathBuf}, + process::exit, +}; use cli_utils::legacy::{display::md, env::current_locales, levenshtein_distance}; use just_enough_vcs_cli::{ @@ -23,6 +27,7 @@ use just_progress::{ }; use log::{LevelFilter, error, info, trace, warn}; use rust_i18n::{set_locale, t}; +use tokio::io::AsyncReadExt; rust_i18n::i18n!("resources/locales/jvn", fallback = "en"); @@ -115,6 +120,18 @@ async fn main() { info!("{}", t!("verbose.user_input", command = args.join(" "))); + // Read pipe inpuit + let (stdin_path, stdin_data) = match read_all_from_stdin().await { + Ok((path, data)) => { + if data.is_empty() { + (None, None) + } else { + (path, Some(data)) + } + } + Err(_) => (None, None), + }; + // Build process future let args_clone = args.clone(); let process_future = jv_cmd_process( @@ -124,6 +141,8 @@ async fn main() { confirmed, args: args.clone(), lang, + stdin_path, + stdin_data, }, renderer_override, ); @@ -198,6 +217,35 @@ async fn main() { } } +/// Read path or raw information from standard input +async fn read_all_from_stdin() -> tokio::io::Result<(Option<PathBuf>, Vec<u8>)> { + if atty::is(atty::Stream::Stdin) { + return Ok((None, Vec::new())); + } + + let mut stdin = tokio::io::stdin(); + let mut buffer = Vec::new(); + + stdin.read_to_end(&mut buffer).await?; + + if buffer.is_empty() { + return Ok((None, Vec::new())); + } + + let path = if let Ok(input_str) = String::from_utf8(buffer.clone()) { + let trimmed = input_str.trim(); + if !trimmed.is_empty() && Path::new(trimmed).exists() { + Some(PathBuf::from(trimmed)) + } else { + None + } + } else { + None + }; + + Ok((path, buffer)) +} + fn handle_no_matching_command_error(args: Vec<String>) { let mut similar_nodes: Vec<String> = Vec::new(); for node in jv_cmd_nodes() { |
