added unit out

master
Avril 3 years ago
parent 03af2f2ed9
commit c5dd15824a
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -15,12 +15,14 @@ pub fn usage() -> !
println!("Unit conversion v{}", env!("CARGO_PKG_VERSION")); println!("Unit conversion v{}", env!("CARGO_PKG_VERSION"));
println!(" by {} with <3 (license GPL3+)", env!("CARGO_PKG_AUTHORS")); println!(" by {} with <3 (license GPL3+)", env!("CARGO_PKG_AUTHORS"));
println!(); 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: {} <unit> <value>", prog_name()); println!("usage: {} <unit> <value>", prog_name());
println!("usage: {} --help", prog_name()); println!("usage: {} --help", prog_name());
println!(); println!();
//TODO: generalise units //TODO: generalise units
println!(r#"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) std::process::exit(0)
} }

@ -21,19 +21,21 @@ impl Conversion for Bytes
type Output = u64; type Output = u64;
fn convert(&self, input: &str) -> Result<Self::Output, Self::Error> fn convert(&self, input: &str) -> Result<(Self::Output, Option<Self::Unit>), Self::Error>
{ {
#[macro_export] macro_rules! parse { #[macro_export] macro_rules! parse {
($non:expr) => (($non).parse::<u64>().map_err(|e| ConversionError(format!("Failed to parse u64: {}", e)))?) ($non:expr) => (($non).parse::<u64>().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])) { let (o, u) = match input.char_indices().last().map(|(idx, chr)| (chr.to_lowercase().next().unwrap(), &input[..idx])) {
Some((chr, _)) if chr.is_numeric() => Ok(parse!(input)), 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))), Some((chr, _)) => return Err(ConversionError(format!("Unknown suffix {}", chr))),
None => Ok(0), None => (0, 1),
} };
Ok((o * u, Some(u)))
} }
} }

@ -9,9 +9,10 @@ pub trait Conversion
const UNIT: &'static str; const UNIT: &'static str;
type Output: fmt::Display; type Output: fmt::Display;
type Unit: fmt::Display = Self::Output;
type Error: Into<ConversionError> = ConversionError; type Error: Into<ConversionError> = ConversionError;
fn convert(&self, input: &str) -> Result<Self::Output, Self::Error>; fn convert(&self, input: &str) -> Result<(Self::Output, Option<Self::Unit>), Self::Error>;
} }
#[derive(Debug)] #[derive(Debug)]
@ -34,11 +35,22 @@ impl From<Infallible> for ConversionError
} }
} }
fn print_output<T,U>((value, units): (T, Option<U>))
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. /// Dispatch a conversion of `value` for type `unit` and print the result to stdout.
pub fn dispatch_out(unit: impl AsRef<str>, value: impl AsRef<str>) -> Result<(), ConversionError> pub fn dispatch_out(unit: impl AsRef<str>, value: impl AsRef<str>) -> Result<(), ConversionError>
{ {
match unit.as_ref() { 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))), name => return Err(ConversionError(format!("Unknown unit {}", name))),
} }

Loading…
Cancel
Save