@@ -147,7 +147,7 @@ pub struct RawDataPart {
147
147
}
148
148
149
149
/// SI prefixes for the human readable part
150
- #[ derive( Eq , PartialEq , Debug ) ]
150
+ #[ derive( Eq , PartialEq , Debug , Clone , Copy ) ]
151
151
pub enum SiPrefix {
152
152
/// 10^-3
153
153
Milli ,
@@ -170,6 +170,14 @@ impl SiPrefix {
170
170
& SiPrefix :: Pico => 1 ,
171
171
}
172
172
}
173
+
174
+ /// Returns all enum variants of `SiPrefix` sorted in descending order of their associated
175
+ /// multiplier.
176
+ pub fn values_desc ( ) -> & ' static [ SiPrefix ] {
177
+ use SiPrefix :: * ;
178
+ static VALUES : [ SiPrefix ; 4 ] = [ Milli , Micro , Nano , Pico ] ;
179
+ & VALUES
180
+ }
173
181
}
174
182
175
183
#[ derive( Eq , PartialEq , Debug , Clone ) ]
@@ -317,11 +325,14 @@ impl<D: tb::Bool, H: tb::Bool> InvoiceBuilder<D, H> {
317
325
}
318
326
}
319
327
320
- /// Sets the amount in pico BTC.
328
+ /// Sets the amount in pico BTC. The optimal SI prefix is choosen automatically.
321
329
pub fn amount_pico_btc ( mut self , amount : u64 ) -> Self {
322
- // TODO: calculate optimal SI prefix
323
- self . amount = Some ( amount) ;
324
- self . si_prefix = None ;
330
+ let biggest_possible_si_prefix = SiPrefix :: values_desc ( )
331
+ . iter ( )
332
+ . find ( |prefix| amount % prefix. multiplier ( ) == 0 )
333
+ . expect ( "Pico should always match" ) ;
334
+ self . amount = Some ( amount / biggest_possible_si_prefix. multiplier ( ) ) ;
335
+ self . si_prefix = Some ( * biggest_possible_si_prefix) ;
325
336
self
326
337
}
327
338
@@ -1056,4 +1067,30 @@ mod test {
1056
1067
1057
1068
assert ! ( new_signed. check_signature( ) ) ;
1058
1069
}
1070
+
1071
+ #[ test]
1072
+ fn test_builder_amount ( ) {
1073
+ use :: * ;
1074
+
1075
+ let invoice = InvoiceBuilder :: new ( Currency :: Bitcoin )
1076
+ . description ( "Test" . into ( ) )
1077
+ . payment_hash ( [ 0 ; 32 ] )
1078
+ . amount_pico_btc ( 15000 )
1079
+ . build_raw ( )
1080
+ . unwrap ( ) ;
1081
+
1082
+ assert_eq ! ( invoice. hrp. si_prefix, Some ( SiPrefix :: Nano ) ) ;
1083
+ assert_eq ! ( invoice. hrp. raw_amount, Some ( 15 ) ) ;
1084
+
1085
+
1086
+ let invoice = InvoiceBuilder :: new ( Currency :: Bitcoin )
1087
+ . description ( "Test" . into ( ) )
1088
+ . payment_hash ( [ 0 ; 32 ] )
1089
+ . amount_pico_btc ( 1500 )
1090
+ . build_raw ( )
1091
+ . unwrap ( ) ;
1092
+
1093
+ assert_eq ! ( invoice. hrp. si_prefix, Some ( SiPrefix :: Pico ) ) ;
1094
+ assert_eq ! ( invoice. hrp. raw_amount, Some ( 1500 ) ) ;
1095
+ }
1059
1096
}
0 commit comments