1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
extern crate regex; use regex::Regex; const S: f64 = 1000.0; const M: f64 = S * 60.0; const H: f64 = M * 60.0; const D: f64 = H * 24.0; const Y: f64 = D*365.0 + D/4.0; #[macro_export] macro_rules! ms { ( $val:expr ) => { { __to_ms__($val) } }; ( $val:expr, $fmt:expr ) => { { __to_string__($val, $fmt) } }; } pub fn __to_ms__(val: &str) -> Option<u64> { if val.len() == 0 { None } else { match process(val) { Some(result) => Some(result), None => None } } } pub fn __to_string__(val: u64, long_format: bool) -> String { if long_format { return fmt_long(val); } return fmt_short(val); } fn process(val: &str) -> Option<u64> { if val.len() > 100 { None } else { let re = Regex::new(r"(?i)^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$").unwrap(); match re.captures(val) { Some(caps) => { let n: f64 = caps.get(1).map_or("", |m| m.as_str()).parse().unwrap(); let match2 = caps.get(2).map_or("ms", |m| m.as_str()); let time_type = match2.to_lowercase(); match time_type.as_str() { "years" | "year" | "yrs" | "yr" | "y" => Some((n * Y).round() as u64), "days" | "day" | "d" => Some((n * D).round() as u64), "hours" | "hour" | "hrs" | "hr" | "h" => Some((n * H).round() as u64), "minutes" | "minute" | "mins" | "min" | "m" => Some((n * M).round() as u64), "seconds" | "second" | "secs" | "sec" | "s" => Some((n * S).round() as u64), "milliseconds" | "millisecond" | "msecs" | "msec" | "ms" => Some(n.round() as u64), _ => Some(0) } }, None => None } } } fn fmt_long(val: u64) -> String { let ms = val as f64; if ms >= D { return plural(ms, D, "day"); } if ms >= H { return plural(ms, H, "hour"); } if ms >= M { return plural(ms, M, "minute"); } if ms >= S { return plural(ms, S, "second"); } return format!("{} ms", val); } fn fmt_short(val: u64) -> String { let result: u64; let ms = val as f64; if ms >= D { result = (ms / D).round() as u64; return format!("{}d", result); } if ms >= H { result = (ms / H).round() as u64; return format!("{}h", result); } if ms >= M { result = (ms / M).round() as u64; return format!("{}m", result); } if ms >= S { result = (ms / S).round() as u64; return format!("{}s", result); } return format!("{}ms", val); } fn plural(ms: f64, n: f64, name: &str) -> String { let result = (ms/n).round() as u64; if ms < n+n/2.0 { return format!("{} {}", result, name); } return format!("{} {}s", result, name); }