@@ -9,22 +9,73 @@ pub struct AssertEq2Error {
99 pub lhs : Value ,
1010 pub span_rhs : Span ,
1111 pub rhs : Value ,
12+ /// When both values are quantities, stores lhs converted to rhs's unit.
13+ pub lhs_converted : Option < Quantity > ,
14+ /// When both values are quantities, stores the absolute difference (in rhs's unit).
15+ pub diff : Option < Quantity > ,
16+ }
17+
18+ impl AssertEq2Error {
19+ /// Returns formatted display strings for lhs and rhs values.
20+ /// When both values are quantities with different units, lhs is shown
21+ /// converted to rhs's unit with the original in parentheses.
22+ pub fn fmt_values ( & self ) -> ( String , String ) {
23+ let rhs_str = format ! ( "{}" , self . rhs) ;
24+ let lhs_str = if let Some ( ref lhs_converted) = self . lhs_converted {
25+ let lhs_converted_str = format ! ( "{lhs_converted}" ) ;
26+ if let Value :: Quantity ( ref lhs_q) = self . lhs
27+ && lhs_converted. unit ( ) != lhs_q. unit ( )
28+ {
29+ return ( format ! ( "{lhs_converted_str} ({})" , self . lhs) , rhs_str) ;
30+ }
31+ lhs_converted_str
32+ } else {
33+ format ! ( "{}" , self . lhs)
34+ } ;
35+ ( lhs_str, rhs_str)
36+ }
37+
38+ fn is_floating_point_inaccuracy ( & self ) -> bool {
39+ if let Some ( ref diff) = self . diff {
40+ if let Some ( ref lhs_converted) = self . lhs_converted {
41+ let diff_val = diff. unsafe_value ( ) . to_f64 ( ) . abs ( ) ;
42+ let lhs_val = lhs_converted. unsafe_value ( ) . to_f64 ( ) . abs ( ) ;
43+
44+ if let Value :: Quantity ( ref rhs_q) = self . rhs {
45+ let rhs_val = rhs_q. unsafe_value ( ) . to_f64 ( ) . abs ( ) ;
46+ let max_val = lhs_val. max ( rhs_val) ;
47+ return max_val > 0.0 && diff_val / max_val < 1e-9 ;
48+ }
49+ }
50+ }
51+ false
52+ }
1253}
1354
1455impl Display for AssertEq2Error {
1556 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
16- let optional_message = if format ! ( "{}" , self . lhs) == format ! ( "{}" , self . rhs) {
17- "\n Note: The two printed values appear to be the same, this may be due to floating point precision errors.\n \
18- For dimension types you may want to test approximate equality instead: assert_eq(q1, q2, ε)."
57+ let ( lhs_str, rhs_str) = self . fmt_values ( ) ;
58+
59+ let fp_note = if self . is_floating_point_inaccuracy ( ) {
60+ "\n Note: this is likely due to floating point inaccuracy. \
61+ Consider testing approximate equality instead: assert_eq(q1, q2, ε)."
1962 } else {
2063 ""
2164 } ;
2265
23- write ! (
24- f,
25- "Assertion failed because the following two values are not the same:\n {}\n {}{}" ,
26- self . lhs, self . rhs, optional_message
27- )
66+ if let Some ( ref diff) = self . diff {
67+ write ! (
68+ f,
69+ "Assertion failed because the following two quantities differ by {diff}:\
70+ \n {lhs_str}\n {rhs_str}{fp_note}",
71+ )
72+ } else {
73+ write ! (
74+ f,
75+ "Assertion failed because the following two values are not the same:\
76+ \n {lhs_str}\n {rhs_str}",
77+ )
78+ }
2879 }
2980}
3081
0 commit comments