From 73bdfb190e369d5753aebfc5be22cea09128d997 Mon Sep 17 00:00:00 2001 From: Chris Warburton Date: Fri, 11 Jul 2025 20:27:43 +0100 Subject: [PATCH 1/2] cli: write output unadulterated Avoid extra newlines, or additions like "Result: ", since they make the command less useful. --- cli/main.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cli/main.rs b/cli/main.rs index a595b82..82c2db3 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -1,5 +1,6 @@ use std::fmt; use std::str::FromStr; +use std::io::{self, Read, Write}; use anyhow::{anyhow, Error, Result}; use multibase::Base; @@ -119,13 +120,13 @@ impl From for Base { fn encode(base: StrBase, input: &[u8]) -> Result<()> { log::debug!("Encode {:?} with {}", input, base); let result = multibase::encode(base.into(), input); - println!("Result: {}", result); + print!("{}", result); Ok(()) } fn decode(input: &str) -> Result<()> { log::debug!("Decode {:?}", input); - let (base, result) = multibase::decode(input)?; - println!("Result: {}, {:?}", StrBase(base), result); + let (_, result) = multibase::decode(input)?; + io::stdout().write_all(&result)?; Ok(()) } From 60d84608e13179aba5a0535a49f9fde138f790c8 Mon Sep 17 00:00:00 2001 From: Chris Warburton Date: Fri, 11 Jul 2025 20:32:50 +0100 Subject: [PATCH 2/2] cli: read data from stdin if no '-i' argument is given This is especially useful for binary data, which may not survive in an argument list (e.g. due to the presence of NUL bytes). The 'encode' and 'decode' commands are now exact inverses of each other, so data will roundtrip correctly, e.g. $ echo "hello world" | ./multibase encode | ./multibase decode hello world $ echo "hello world" | ./multibase encode | ./multibase decode | ./multibase encode z2yGEbwRFyhPZZckJm $ echo "hello world" | ./multibase encode z2yGEbwRFyhPZZckJm --- cli/main.rs | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/cli/main.rs b/cli/main.rs index 82c2db3..0a71527 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -20,15 +20,15 @@ enum Mode { /// The base to use for encoding. #[structopt(short = "b", long = "base", default_value = "base58btc")] base: StrBase, - /// The data need to be encoded. + /// The data to encode. Reads from stdin if not provided. #[structopt(short = "i", long = "input")] - input: String, + input: Option, }, #[structopt(name = "decode")] Decode { - /// The data need to be decoded. + /// The data to decode. Reads from stdin if not provided. #[structopt(short = "i", long = "input")] - input: String, + input: Option, }, } @@ -36,8 +36,26 @@ fn main() -> Result<()> { env_logger::init(); let opts = Opts::from_args(); match opts.mode { - Mode::Encode { base, input } => encode(base, input.as_bytes()), - Mode::Decode { input } => decode(&input), + Mode::Encode { base, input } => { + let input_bytes = if let Some(s) = input { + s.into_bytes() + } else { + let mut buf = Vec::new(); + io::stdin().read_to_end(&mut buf)?; + buf + }; + encode(base, &input_bytes) + } + Mode::Decode { input } => { + let input_str = if let Some(s) = input { + s + } else { + let mut buf = String::new(); + io::stdin().read_to_string(&mut buf)?; + buf + }; + decode(&input_str) + } } }