@@ -1138,64 +1138,191 @@ fn trailing_zeros_for_amount() {
11381138}
11391139
11401140#[ test]
1141- #[ allow( clippy:: op_ref) ]
1141+ fn add_sub_combos ( ) {
1142+ // Checks lhs op rhs for all reference combos.
1143+ macro_rules! check_ref {
1144+ ( $( $lhs: ident $op: tt $rhs: ident = $ans: ident) ;* $( ; ) ?) => {
1145+ $(
1146+ assert_eq!( $lhs $op $rhs, $ans) ;
1147+ assert_eq!( & $lhs $op $rhs, $ans) ;
1148+ assert_eq!( $lhs $op & $rhs, $ans) ;
1149+ assert_eq!( & $lhs $op & $rhs, $ans) ;
1150+ ) *
1151+ }
1152+ }
1153+
1154+ // Checks lhs op rhs for all amount and `NumOpResult` combos.
1155+ macro_rules! check_res {
1156+ ( $( $amount: ident, $op: tt, $lhs: literal, $rhs: literal, $ans: literal) ;* $( ; ) ?) => {
1157+ $(
1158+ let amt = |sat| $amount:: from_sat( sat) ;
1159+
1160+ let sat_lhs = amt( $lhs) ;
1161+ let sat_rhs = amt( $rhs) ;
1162+
1163+ let res_lhs = NumOpResult :: from( sat_lhs) ;
1164+ let res_rhs = NumOpResult :: from( sat_rhs) ;
1165+
1166+ let ans = NumOpResult :: from( amt( $ans) ) ;
1167+
1168+ check_ref! {
1169+ sat_lhs $op sat_rhs = ans;
1170+ sat_lhs $op res_rhs = ans;
1171+ res_lhs $op sat_rhs = ans;
1172+ res_lhs $op res_rhs = ans;
1173+ }
1174+ ) *
1175+ }
1176+ }
1177+
1178+ // Checks lhs op rhs for both amount types.
1179+ macro_rules! check_op {
1180+ ( $( $lhs: literal $op: tt $rhs: literal = $ans: literal) ;* $( ; ) ?) => {
1181+ $(
1182+ check_res!( Amount , $op, $lhs, $rhs, $ans) ;
1183+ check_res!( SignedAmount , $op, $lhs, $rhs, $ans) ;
1184+ ) *
1185+ }
1186+ }
1187+
1188+ // We do not currently support division involving `NumOpResult` and an amount type.
1189+ check_op ! {
1190+ 307 + 461 = 768 ;
1191+ 461 - 307 = 154 ;
1192+ }
1193+ }
1194+
1195+ #[ test]
11421196fn unsigned_addition ( ) {
11431197 let sat = Amount :: from_sat;
11441198
1145- let one = sat ( 1 ) ;
1146- let two = sat ( 2 ) ;
1147- let three = sat ( 3 ) ;
1199+ assert_eq ! ( sat( 0 ) + sat( 0 ) , NumOpResult :: from( sat( 0 ) ) ) ;
1200+ assert_eq ! ( sat( 0 ) + sat( 307 ) , NumOpResult :: from( sat( 307 ) ) ) ;
1201+ assert_eq ! ( sat( 307 ) + sat( 0 ) , NumOpResult :: from( sat( 307 ) ) ) ;
1202+ assert_eq ! ( sat( 307 ) + sat( 461 ) , NumOpResult :: from( sat( 768 ) ) ) ;
1203+ assert_eq ! ( sat( 0 ) + Amount :: MAX_MONEY , NumOpResult :: from( Amount :: MAX_MONEY ) ) ;
1204+ }
11481205
1149- assert ! ( ( one + two) == three. into( ) ) ;
1150- assert ! ( ( one + two) == three. into( ) ) ;
1151- assert ! ( ( & one + two) == three. into( ) ) ;
1152- assert ! ( ( one + & two) == three. into( ) ) ;
1153- assert ! ( ( & one + & two) == three. into( ) ) ;
1206+ #[ test]
1207+ fn signed_addition ( ) {
1208+ let ssat = SignedAmount :: from_sat;
1209+
1210+ assert_eq ! ( ssat( 0 ) + ssat( 0 ) , NumOpResult :: from( ssat( 0 ) ) ) ;
1211+ assert_eq ! ( ssat( 0 ) + ssat( 307 ) , NumOpResult :: from( ssat( 307 ) ) ) ;
1212+ assert_eq ! ( ssat( 307 ) + ssat( 0 ) , NumOpResult :: from( ssat( 307 ) ) ) ;
1213+ assert_eq ! ( ssat( 307 ) + ssat( 461 ) , NumOpResult :: from( ssat( 768 ) ) ) ;
1214+ assert_eq ! ( ssat( 0 ) + SignedAmount :: MAX_MONEY , NumOpResult :: from( SignedAmount :: MAX_MONEY ) ) ;
1215+
1216+ assert_eq ! ( ssat( 0 ) + ssat( -307 ) , NumOpResult :: from( ssat( -307 ) ) ) ;
1217+ assert_eq ! ( ssat( -307 ) + ssat( 0 ) , NumOpResult :: from( ssat( -307 ) ) ) ;
1218+ assert_eq ! ( ssat( -307 ) + ssat( 461 ) , NumOpResult :: from( ssat( 154 ) ) ) ;
1219+ assert_eq ! ( ssat( 307 ) + ssat( -461 ) , NumOpResult :: from( ssat( -154 ) ) ) ;
1220+ assert_eq ! ( ssat( -307 ) + ssat( -461 ) , NumOpResult :: from( ssat( -768 ) ) ) ;
1221+ assert_eq ! (
1222+ SignedAmount :: MAX_MONEY + -SignedAmount :: MAX_MONEY ,
1223+ NumOpResult :: from( SignedAmount :: ZERO )
1224+ ) ;
11541225}
11551226
11561227#[ test]
1157- #[ allow( clippy:: op_ref) ]
1158- fn unsigned_subtract ( ) {
1228+ fn unsigned_subtraction ( ) {
11591229 let sat = Amount :: from_sat;
11601230
1161- let one = sat ( 1 ) ;
1162- let two = sat ( 2 ) ;
1163- let three = sat ( 3 ) ;
1231+ assert_eq ! ( sat( 0 ) - sat( 0 ) , NumOpResult :: from( sat( 0 ) ) ) ;
1232+ assert_eq ! ( sat( 307 ) - sat( 0 ) , NumOpResult :: from( sat( 307 ) ) ) ;
1233+ assert_eq ! ( sat( 461 ) - sat( 307 ) , NumOpResult :: from( sat( 154 ) ) ) ;
1234+ }
1235+
1236+ #[ test]
1237+ fn signed_subtraction ( ) {
1238+ let ssat = SignedAmount :: from_sat;
11641239
1165- assert ! ( three - two == one. into( ) ) ;
1166- assert ! ( & three - two == one. into( ) ) ;
1167- assert ! ( three - & two == one. into( ) ) ;
1168- assert ! ( & three - & two == one. into( ) ) ;
1240+ assert_eq ! ( ssat( 0 ) - ssat( 0 ) , NumOpResult :: from( ssat( 0 ) ) ) ;
1241+ assert_eq ! ( ssat( 0 ) - ssat( 307 ) , NumOpResult :: from( ssat( -307 ) ) ) ;
1242+ assert_eq ! ( ssat( 307 ) - ssat( 0 ) , NumOpResult :: from( ssat( 307 ) ) ) ;
1243+ assert_eq ! ( ssat( 307 ) - ssat( 461 ) , NumOpResult :: from( ssat( -154 ) ) ) ;
1244+ assert_eq ! ( ssat( 0 ) - SignedAmount :: MAX_MONEY , NumOpResult :: from( -SignedAmount :: MAX_MONEY ) ) ;
1245+
1246+ assert_eq ! ( ssat( 0 ) - ssat( -307 ) , NumOpResult :: from( ssat( 307 ) ) ) ;
1247+ assert_eq ! ( ssat( -307 ) - ssat( 0 ) , NumOpResult :: from( ssat( -307 ) ) ) ;
1248+ assert_eq ! ( ssat( -307 ) - ssat( 461 ) , NumOpResult :: from( ssat( -768 ) ) ) ;
1249+ assert_eq ! ( ssat( 307 ) - ssat( -461 ) , NumOpResult :: from( ssat( 768 ) ) ) ;
1250+ assert_eq ! ( ssat( -307 ) - ssat( -461 ) , NumOpResult :: from( ssat( 154 ) ) ) ;
11691251}
11701252
11711253#[ test]
1172- # [ allow ( clippy :: op_ref ) ]
1173- fn signed_addition ( ) {
1254+ fn op_int_combos ( ) {
1255+ let sat = Amount :: from_sat ;
11741256 let ssat = SignedAmount :: from_sat;
11751257
1176- let one = ssat ( 1 ) ;
1177- let two = ssat ( 2 ) ;
1178- let three = ssat ( 3 ) ;
1258+ let res = |sat| NumOpResult :: from ( Amount :: from_sat ( sat) ) ;
1259+ let sres = |ssat| NumOpResult :: from ( SignedAmount :: from_sat ( ssat) ) ;
1260+
1261+ assert_eq ! ( sat( 23 ) * 31 , res( 713 ) ) ;
1262+ assert_eq ! ( ssat( 23 ) * 31 , sres( 713 ) ) ;
1263+ assert_eq ! ( res( 23 ) * 31 , res( 713 ) ) ;
1264+ assert_eq ! ( sres( 23 ) * 31 , sres( 713 ) ) ;
1265+
1266+ assert_eq ! ( 31 * sat( 23 ) , res( 713 ) ) ;
1267+ assert_eq ! ( 31 * ssat( 23 ) , sres( 713 ) ) ;
1268+ assert_eq ! ( 31 * res( 23 ) , res( 713 ) ) ;
1269+ assert_eq ! ( 31 * sres( 23 ) , sres( 713 ) ) ;
1270+
1271+ // No remainder.
1272+ assert_eq ! ( sat( 1897 ) / 7 , res( 271 ) ) ;
1273+ assert_eq ! ( ssat( 1897 ) / 7 , sres( 271 ) ) ;
1274+ assert_eq ! ( res( 1897 ) / 7 , res( 271 ) ) ;
1275+ assert_eq ! ( sres( 1897 ) / 7 , sres( 271 ) ) ;
1276+
1277+ // Truncation works as expected.
1278+ assert_eq ! ( sat( 1901 ) / 7 , res( 271 ) ) ;
1279+ assert_eq ! ( ssat( 1901 ) / 7 , sres( 271 ) ) ;
1280+ assert_eq ! ( res( 1901 ) / 7 , res( 271 ) ) ;
1281+ assert_eq ! ( sres( 1901 ) / 7 , sres( 271 ) ) ;
1282+
1283+ // No remainder.
1284+ assert_eq ! ( sat( 1897 ) % 7 , res( 0 ) ) ;
1285+ assert_eq ! ( ssat( 1897 ) % 7 , sres( 0 ) ) ;
1286+ assert_eq ! ( res( 1897 ) % 7 , res( 0 ) ) ;
1287+ assert_eq ! ( sres( 1897 ) % 7 , sres( 0 ) ) ;
1288+
1289+ // Remainder works as expected.
1290+ assert_eq ! ( sat( 1901 ) % 7 , res( 4 ) ) ;
1291+ assert_eq ! ( ssat( 1901 ) % 7 , sres( 4 ) ) ;
1292+ assert_eq ! ( res( 1901 ) % 7 , res( 4 ) ) ;
1293+ assert_eq ! ( sres( 1901 ) % 7 , sres( 4 ) ) ;
1294+ }
1295+
1296+ #[ test]
1297+ fn unsigned_amount_div_by_amount ( ) {
1298+ let sat = Amount :: from_sat;
1299+
1300+ assert_eq ! ( sat( 0 ) / sat( 7 ) , 0 ) ;
1301+ assert_eq ! ( sat( 1897 ) / sat( 7 ) , 271 ) ;
1302+ }
11791303
1180- assert ! ( one + two == three . into ( ) ) ;
1181- assert ! ( & one + two == three . into ( ) ) ;
1182- assert ! ( one + & two == three . into ( ) ) ;
1183- assert ! ( & one + & two == three . into ( ) ) ;
1304+ # [ test ]
1305+ # [ should_panic ( expected = "attempt to divide by zero" ) ]
1306+ fn unsigned_amount_div_by_amount_zero ( ) {
1307+ let _ = Amount :: from_sat ( 1897 ) / Amount :: ZERO ;
11841308}
11851309
11861310#[ test]
1187- #[ allow( clippy:: op_ref) ]
1188- fn signed_subtract ( ) {
1311+ fn signed_amount_div_by_amount ( ) {
11891312 let ssat = SignedAmount :: from_sat;
11901313
1191- let one = ssat ( 1 ) ;
1192- let two = ssat ( 2 ) ;
1193- let three = ssat ( 3 ) ;
1314+ assert_eq ! ( ssat( 0 ) / ssat( 7 ) , 0 ) ;
1315+
1316+ assert_eq ! ( ssat( 1897 ) / ssat( 7 ) , 271 ) ;
1317+ assert_eq ! ( ssat( 1897 ) / ssat( -7 ) , -271 ) ;
1318+ assert_eq ! ( ssat( -1897 ) / ssat( 7 ) , -271 ) ;
1319+ assert_eq ! ( ssat( -1897 ) / ssat( -7 ) , 271 ) ;
1320+ }
11941321
1195- assert ! ( three - two == one . into ( ) ) ;
1196- assert ! ( & three - two == one . into ( ) ) ;
1197- assert ! ( three - & two == one . into ( ) ) ;
1198- assert ! ( & three - & two == one . into ( ) ) ;
1322+ # [ test ]
1323+ # [ should_panic ( expected = "attempt to divide by zero" ) ]
1324+ fn signed_amount_div_by_amount_zero ( ) {
1325+ let _ = SignedAmount :: from_sat ( 1897 ) / SignedAmount :: ZERO ;
11991326}
12001327
12011328#[ test]
@@ -1300,6 +1427,15 @@ fn num_op_result_ops_integer() {
13001427 }
13011428 }
13021429 check_op ! {
1430+ // Operations on an amount type and an integer.
1431+ let _ = sat * 3_u64 ; // Explicit type for the benefit of the reader.
1432+ let _ = sat / 3 ;
1433+ let _ = sat % 3 ;
1434+
1435+ let _ = ssat * 3_i64 ; // Explicit type for the benefit of the reader.
1436+ let _ = ssat / 3 ;
1437+ let _ = ssat % 3 ;
1438+
13031439 // Operations on a `NumOpResult` and integer.
13041440 let _ = res * 3_u64 ; // Explicit type for the benefit of the reader.
13051441 let _ = res / 3 ;
0 commit comments