|
|
|
use super::*;
|
|
|
|
use smallmap::Map;
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Bytes;
|
|
|
|
|
|
|
|
const KB: u64 = 1024;
|
|
|
|
|
|
|
|
lazy_static! {
|
|
|
|
static ref SUFFIX: Map<char, u64> = smallmap::smallmap! {
|
|
|
|
{'k' => KB},
|
|
|
|
{'m' => KB * KB},
|
|
|
|
{'g' => KB * KB * KB},
|
|
|
|
{'p' => KB * KB * KB * KB},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Conversion for Bytes
|
|
|
|
{
|
|
|
|
const UNIT: &'static str = "bytes";
|
|
|
|
|
|
|
|
type Output = u64;
|
|
|
|
|
|
|
|
fn convert(&self, input: &str) -> Result<(Self::Output, Option<Self::Unit>), Self::Error>
|
|
|
|
{
|
|
|
|
#[macro_export] macro_rules! parse {
|
|
|
|
($non:expr) => (($non).parse::<u64>().map_err(|e| ConversionError(format!("Failed to parse u64: {}", e)))?)
|
|
|
|
}
|
|
|
|
|
|
|
|
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) => (parse!(non), *SUFFIX.get(chr).unwrap()),
|
|
|
|
|
|
|
|
Some((chr, _)) => return Err(ConversionError(format!("Unknown suffix {}", chr))),
|
|
|
|
None => (0, 1),
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok((o * u, Some(u)))
|
|
|
|
}
|
|
|
|
}
|