From f24bd948a5dcb9bd4b026f6ba99db4849dd91d23 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..0445d9c 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -1,4 +1,5 @@ use std::fmt; +use std::io::{self, Read, Write}; use std::str::FromStr; use anyhow::{anyhow, Error, Result}; @@ -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 8646d0f7bf01a98f7b532e62440ce2dee038174c 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 | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/cli/main.rs b/cli/main.rs index 0445d9c..529b6d0 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,28 @@ 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 = match input { + Some(s) => s.into_bytes(), + None => { + let mut buf = Vec::new(); + io::stdin().read_to_end(&mut buf)?; + buf + } + }; + encode(base, &input_bytes) + } + Mode::Decode { input } => { + let input_str = match input { + Some(s) => s, + None => { + let mut buf = String::new(); + io::stdin().read_to_string(&mut buf)?; + buf + } + }; + decode(&input_str) + } } }