#[macro_export] /// Assert that two values absolute difference is less than a particular tolerance. macro_rules! assert_approx_eq { ($a:expr, $b:expr, $tol:expr) => ({ let (a, b, tol) = (&$a, &$b, &$tol); assert!((*a - *b).abs() < *tol, "{} is not approx equal to {} at tol {}", *a, *b, *tol); }) } #[allow(dead_code)] pub enum MemorySize { Bit, Byte, Kilobit, Kilobyte, Megabit, Megabyte, Gigabit, Gigabyte, } impl MemorySize { pub fn in_bytes(&self) -> usize { match *self { MemorySize::Bit => 0, MemorySize::Byte => 1, MemorySize::Kilobit => 1_000 / 8, MemorySize::Kilobyte => 1_000, MemorySize::Megabit => 1_000_000 / 8, MemorySize::Megabyte => 1_000_000, MemorySize::Gigabit => 1_000_000_000 / 8, MemorySize::Gigabyte => 1_000_000_000, } } #[allow(dead_code)] pub fn in_bits(&self) -> usize { match *self { MemorySize::Bit => 1, _ => self.in_bytes() * 8, } } } #[cfg(test)] mod tests { use std::panic; #[test] quickcheck! { fn assert_approx_eq_no_panic_close(a: f64, b: f64) -> bool { assert_approx_eq!(a, b, (a - b).abs() * 2.); true } } #[test] quickcheck! { fn assert_approx_eq_panics_far(a: f64, b: f64) -> bool { panic::catch_unwind(|| assert_approx_eq!(a, b, (a - b).abs() / 2.)).is_err() } } }