cs_mwc_bch/util/
amount.rs1use std::fmt;
4use util::{Error, Result};
5
6#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
8pub enum Units {
9 Bch,
11 Bits,
13 Sats,
15}
16
17impl Units {
18 pub fn parse(s: &str) -> Result<Units> {
19 let s = s.to_lowercase();
20 if s == "bch" || s == "bitcoin" {
21 return Ok(Units::Bch);
22 } else if s == "bit" || s == "bits" {
23 return Ok(Units::Bits);
24 } else if s == "sat" || s == "sats" {
25 return Ok(Units::Sats);
26 } else {
27 let msg = format!("Unknown units: {}", s);
28 return Err(Error::BadArgument(msg));
29 }
30 }
31}
32
33#[derive(PartialEq, Eq, Hash, Clone, Copy)]
35pub struct Amount(pub i64);
36
37impl Amount {
38 pub fn from(amount: f64, units: Units) -> Amount {
40 match units {
41 Units::Bch => Amount((amount * 100_000_000.) as i64),
42 Units::Bits => Amount((amount * 100.) as i64),
43 Units::Sats => Amount(amount as i64),
44 }
45 }
46
47 pub fn to(&self, units: Units) -> f64 {
49 match units {
50 Units::Bch => self.0 as f64 / 100_000_000.,
51 Units::Bits => self.0 as f64 / 100.,
52 Units::Sats => self.0 as f64,
53 }
54 }
55}
56impl fmt::Debug for Amount {
57 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
58 f.write_str(&format!("{} bch", self.to(Units::Bch)))
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn from_to() {
68 assert!(Amount(0).to(Units::Bch) == 0.);
69 assert!(Amount(0).to(Units::Bits) == 0.);
70 assert!(Amount(0).to(Units::Sats) == 0.);
71
72 assert!(Amount(1).to(Units::Bch) == 0.00000001);
73 assert!(Amount(1).to(Units::Bits) == 0.01);
74 assert!(Amount(1).to(Units::Sats) == 1.);
75
76 assert!(Amount(9).to(Units::Bch) == 0.00000009);
77 assert!(Amount(9).to(Units::Bits) == 0.09);
78 assert!(Amount(9).to(Units::Sats) == 9.);
79
80 assert!(Amount::from(0., Units::Bch).0 == 0);
81 assert!(Amount::from(0., Units::Bits).0 == 0);
82 assert!(Amount::from(0., Units::Sats).0 == 0);
83
84 assert!(Amount::from(1., Units::Bch).0 == 100_000_000);
85 assert!(Amount::from(1., Units::Bits).0 == 100);
86 assert!(Amount::from(1., Units::Sats).0 == 1);
87
88 assert!(Amount::from(9., Units::Bch).0 == 900_000_000);
89 assert!(Amount::from(9., Units::Bits).0 == 900);
90 assert!(Amount::from(9., Units::Sats).0 == 9);
91
92 assert!(Amount::from(1., Units::Bch).to(Units::Bch) == 1.);
93 assert!(Amount::from(0.01, Units::Bch).to(Units::Bch) == 0.01);
94 assert!(Amount::from(99., Units::Bits).to(Units::Bits) == 99.);
95 assert!(Amount::from(1., Units::Sats).to(Units::Sats) == 1.);
96 }
97}