assert_be_close/
lib.rs

1use std::fmt::Display;
2
3use num::Float;
4
5/// Asserts that two decimals are equal with the specified precision.
6/// On panic, the function will print the value of the decimal with their debug representations.
7/// 2つの小数が指定した精度で等しいことを保証する。
8/// パニックになると、この関数は小数の値をデバッグ表現とともに出力する。
9///
10/// # Panics
11///
12/// Panic if the value is not equivalent to the specified precision.
13/// 値が指定した精度で等価でなければパニックする。
14///
15/// # Examples
16///
17/// ```should_panic
18/// use assert_be_close::assert_be_close;
19///
20/// assert_be_close(1.0, 1.0001, 3);
21/// assert_be_close(1.0, 1.0001, 4); // panic
22/// ```
23pub fn assert_be_close<T: Float + Display>(left: T, right: T, precision: i32) {
24    let expected_diff = T::from(10.0).unwrap().powi(-precision) / T::from(2.0).unwrap();
25    let received_diff = (left - right).abs();
26
27    if received_diff >= expected_diff {
28        panic!("assertion 'left ≈ right` failed\n left: {}\nright: {}\nreceived_diff: {}\nexpected_diff: {}", left, right, received_diff, expected_diff);
29    }
30}
31
32/// Asserts that two decimals aren't equal with the specified precision.
33/// On panic, the function will print the value of the decimal with their debug representations.
34/// 2つの小数が指定した精度で等しくないことを保証する。
35/// パニックになると、この関数は小数の値をデバッグ表現とともに出力する。
36///
37/// # Panics
38///
39/// Panic if the value is equivalent to the specified precision.
40/// 値が指定した精度で等価であるとパニックする。
41///
42/// # Examples
43///
44/// ```should_panic
45/// use assert_be_close::assert_not_close;
46///
47/// assert_not_close(1.0, 1.0001, 4);
48/// assert_not_close(1.0, 1.0001, 3); // panic
49/// ```
50pub fn assert_not_close<T: Float + Display>(left: T, right: T, precision: i32) {
51    let expected_diff = T::from(10.0).unwrap().powi(-precision) / T::from(2.0).unwrap();
52    let received_diff = (left - right).abs();
53
54    if received_diff <= expected_diff {
55        panic!("assertion 'left != right` failed\n left: {}\nright: {}\nreceived_diff: {}\nexpected_diff: {}", left, right, received_diff, expected_diff);
56    }
57}
58
59
60#[cfg(test)]
61mod test {
62    use super::*;
63
64    #[test]
65    fn assert_be_close_works() {
66        assert_be_close(1.0, 1.0001, 3);
67    }
68
69    #[test]
70    fn assert_not_close_works() {
71        assert_not_close(1.0, 1.0001, 4);
72    }
73}