Skip to content
This repository was archived by the owner on Apr 13, 2021. It is now read-only.

Commit d2ec218

Browse files
committed
Automatically infer the right SI prefix in builder
1 parent c8755e1 commit d2ec218

File tree

1 file changed

+42
-5
lines changed

1 file changed

+42
-5
lines changed

src/lib.rs

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ pub struct RawDataPart {
147147
}
148148

149149
/// SI prefixes for the human readable part
150-
#[derive(Eq, PartialEq, Debug)]
150+
#[derive(Eq, PartialEq, Debug, Clone, Copy)]
151151
pub enum SiPrefix {
152152
/// 10^-3
153153
Milli,
@@ -170,6 +170,14 @@ impl SiPrefix {
170170
&SiPrefix::Pico => 1,
171171
}
172172
}
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+
}
173181
}
174182

175183
#[derive(Eq, PartialEq, Debug, Clone)]
@@ -317,11 +325,14 @@ impl<D: tb::Bool, H: tb::Bool> InvoiceBuilder<D, H> {
317325
}
318326
}
319327

320-
/// Sets the amount in pico BTC.
328+
/// Sets the amount in pico BTC. The optimal SI prefix is choosen automatically.
321329
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);
325336
self
326337
}
327338

@@ -1056,4 +1067,30 @@ mod test {
10561067

10571068
assert!(new_signed.check_signature());
10581069
}
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+
}
10591096
}

0 commit comments

Comments
 (0)