From c5dd15824ab7cd9201550261adab328686eed16b Mon Sep 17 00:00:00 2001 From: Avril Date: Wed, 30 Dec 2020 12:34:43 +0000 Subject: [PATCH] added unit out --- src/arg.rs | 4 +++- src/conv/bytes.rs | 16 +++++++++------- src/conv/mod.rs | 16 ++++++++++++++-- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/arg.rs b/src/arg.rs index 9b2947f..fa16782 100644 --- a/src/arg.rs +++ b/src/arg.rs @@ -15,12 +15,14 @@ pub fn usage() -> ! println!("Unit conversion v{}", env!("CARGO_PKG_VERSION")); println!(" by {} with <3 (license GPL3+)", env!("CARGO_PKG_AUTHORS")); println!(); + println!("This program takes a value with a unit and outputs the smallest value corresponding to that type to `stdout`. It then outputs the multiplyer used to convert this unit to `stderr`, if there is one needed."); + println!(); println!("usage: {} ", prog_name()); println!("usage: {} --help", prog_name()); println!(); //TODO: generalise units println!(r#"Units: - BYTES Convert byte unit into single bytes"#); + BYTES Convert byte unit (k, m, g, p) into single bytes"#); std::process::exit(0) } diff --git a/src/conv/bytes.rs b/src/conv/bytes.rs index d2ce42c..9fe8682 100644 --- a/src/conv/bytes.rs +++ b/src/conv/bytes.rs @@ -21,19 +21,21 @@ impl Conversion for Bytes type Output = u64; - fn convert(&self, input: &str) -> Result + fn convert(&self, input: &str) -> Result<(Self::Output, Option), Self::Error> { #[macro_export] macro_rules! parse { ($non:expr) => (($non).parse::().map_err(|e| ConversionError(format!("Failed to parse u64: {}", e)))?) } - match input.char_indices().last().map(|(idx, chr)| (chr.to_lowercase().next().unwrap(), &input[..idx])) { - Some((chr, _)) if chr.is_numeric() => Ok(parse!(input)), + let (o, u) = match input.char_indices().last().map(|(idx, chr)| (chr.to_lowercase().next().unwrap(), &input[..idx])) { + Some((chr, _)) if chr.is_numeric() => (parse!(input), 1), - Some((ref chr, non)) if SUFFIX.contains_key(chr) => Ok(*SUFFIX.get(chr).unwrap() * parse!(non)), + Some((ref chr, non)) if SUFFIX.contains_key(chr) => (parse!(non), *SUFFIX.get(chr).unwrap()), - Some((chr, _)) => Err(ConversionError(format!("Unknown suffix {}", chr))), - None => Ok(0), - } + Some((chr, _)) => return Err(ConversionError(format!("Unknown suffix {}", chr))), + None => (0, 1), + }; + + Ok((o * u, Some(u))) } } diff --git a/src/conv/mod.rs b/src/conv/mod.rs index fc7c2e5..1610e6f 100644 --- a/src/conv/mod.rs +++ b/src/conv/mod.rs @@ -9,9 +9,10 @@ pub trait Conversion const UNIT: &'static str; type Output: fmt::Display; + type Unit: fmt::Display = Self::Output; type Error: Into = ConversionError; - fn convert(&self, input: &str) -> Result; + fn convert(&self, input: &str) -> Result<(Self::Output, Option), Self::Error>; } #[derive(Debug)] @@ -34,11 +35,22 @@ impl From for ConversionError } } +fn print_output((value, units): (T, Option)) +where T: fmt::Display, + U: fmt::Display +{ + println!("{}", value); + if let Some(units) = units + { + eprintln!("{}", units); + } +} + /// Dispatch a conversion of `value` for type `unit` and print the result to stdout. pub fn dispatch_out(unit: impl AsRef, value: impl AsRef) -> Result<(), ConversionError> { match unit.as_ref() { - bytes::Bytes::UNIT => println!("{}", bytes::Bytes.convert(value.as_ref())?), + bytes::Bytes::UNIT => print_output(bytes::Bytes.convert(value.as_ref())?), name => return Err(ConversionError(format!("Unknown unit {}", name))), }