You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
1.3 KiB

use std::error;
use std::fmt;
use std::convert::Infallible;
pub mod bytes;
pub trait Conversion
{
const UNIT: &'static str;
type Output: fmt::Display;
type Unit: fmt::Display = Self::Output;
type Error: Into<ConversionError> = ConversionError;
fn convert(&self, input: &str) -> Result<(Self::Output, Option<Self::Unit>), Self::Error>;
}
#[derive(Debug)]
pub struct ConversionError(String);
impl error::Error for ConversionError{}
impl fmt::Display for ConversionError
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "conversion failed: {}", self.0)
}
}
impl From<Infallible> for ConversionError
{
fn from(from: Infallible) -> Self
{
match from {}
}
}
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.
pub fn dispatch_out(unit: impl AsRef<str>, value: impl AsRef<str>) -> Result<(), ConversionError>
{
match unit.as_ref() {
bytes::Bytes::UNIT => print_output(bytes::Bytes.convert(value.as_ref())?),
name => return Err(ConversionError(format!("Unknown unit {}", name))),
}
Ok(())
}