@@ -30,11 +30,8 @@ use internals::write_err;
30
30
/// assert_eq!(Amount::from_str("1 cBTC").unwrap(), Amount::from_sat(1_000_000));
31
31
/// assert_eq!(Amount::from_str("1 mBTC").unwrap(), Amount::from_sat(100_000));
32
32
/// assert_eq!(Amount::from_str("1 uBTC").unwrap(), Amount::from_sat(100));
33
- /// assert_eq!(Amount::from_str("10 nBTC").unwrap(), Amount::from_sat(1));
34
- /// assert_eq!(Amount::from_str("10000 pBTC").unwrap(), Amount::from_sat(1));
35
33
/// assert_eq!(Amount::from_str("1 bit").unwrap(), Amount::from_sat(100));
36
34
/// assert_eq!(Amount::from_str("1 sat").unwrap(), Amount::from_sat(1));
37
- /// assert_eq!(Amount::from_str("1000 msats").unwrap(), Amount::from_sat(1));
38
35
/// ```
39
36
#[ derive( Debug , Clone , Copy , Eq , PartialEq , Hash ) ]
40
37
#[ non_exhaustive]
@@ -47,16 +44,10 @@ pub enum Denomination {
47
44
MilliBitcoin ,
48
45
/// uBTC
49
46
MicroBitcoin ,
50
- /// nBTC
51
- NanoBitcoin ,
52
- /// pBTC
53
- PicoBitcoin ,
54
47
/// bits
55
48
Bit ,
56
49
/// satoshi
57
50
Satoshi ,
58
- /// msat
59
- MilliSatoshi ,
60
51
}
61
52
62
53
impl Denomination {
@@ -73,11 +64,8 @@ impl Denomination {
73
64
Denomination :: CentiBitcoin => -6 ,
74
65
Denomination :: MilliBitcoin => -5 ,
75
66
Denomination :: MicroBitcoin => -2 ,
76
- Denomination :: NanoBitcoin => 1 ,
77
- Denomination :: PicoBitcoin => 4 ,
78
67
Denomination :: Bit => -2 ,
79
68
Denomination :: Satoshi => 0 ,
80
- Denomination :: MilliSatoshi => 3 ,
81
69
}
82
70
}
83
71
@@ -88,11 +76,8 @@ impl Denomination {
88
76
Denomination :: CentiBitcoin => "cBTC" ,
89
77
Denomination :: MilliBitcoin => "mBTC" ,
90
78
Denomination :: MicroBitcoin => "uBTC" ,
91
- Denomination :: NanoBitcoin => "nBTC" ,
92
- Denomination :: PicoBitcoin => "pBTC" ,
93
79
Denomination :: Bit => "bits" ,
94
80
Denomination :: Satoshi => "satoshi" ,
95
- Denomination :: MilliSatoshi => "msat" ,
96
81
}
97
82
}
98
83
@@ -103,21 +88,18 @@ impl Denomination {
103
88
"cBTC" | "cbtc" => Some ( Denomination :: CentiBitcoin ) ,
104
89
"mBTC" | "mbtc" => Some ( Denomination :: MilliBitcoin ) ,
105
90
"uBTC" | "ubtc" => Some ( Denomination :: MicroBitcoin ) ,
106
- "nBTC" | "nbtc" => Some ( Denomination :: NanoBitcoin ) ,
107
- "pBTC" | "pbtc" => Some ( Denomination :: PicoBitcoin ) ,
108
91
"bit" | "bits" | "BIT" | "BITS" => Some ( Denomination :: Bit ) ,
109
92
"SATOSHI" | "satoshi" | "SATOSHIS" | "satoshis" | "SAT" | "sat" | "SATS" | "sats" =>
110
93
Some ( Denomination :: Satoshi ) ,
111
- "mSAT" | "msat" | "mSATs" | "msats" => Some ( Denomination :: MilliSatoshi ) ,
112
94
_ => None ,
113
95
}
114
96
}
115
97
}
116
98
117
99
/// These form are ambigous and could have many meanings. For example, M could denote Mega or Milli.
118
100
/// If any of these forms are used, an error type PossiblyConfusingDenomination is returned.
119
- const CONFUSING_FORMS : [ & str ; 9 ] =
120
- [ "Msat " , "Msats " , "MSAT " , "MSATS " , "MSat " , "MSats" , "MBTC" , "Mbtc" , "PBTC "] ;
101
+ const CONFUSING_FORMS : [ & str ; 6 ] =
102
+ [ "MBTC " , "Mbtc " , "CBTC " , "Cbtc " , "UBTC " , "Ubtc " ] ;
121
103
122
104
impl fmt:: Display for Denomination {
123
105
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result { f. write_str ( self . as_str ( ) ) }
@@ -128,11 +110,13 @@ impl FromStr for Denomination {
128
110
129
111
/// Convert from a str to Denomination.
130
112
///
131
- /// Any combination of upper and/or lower case, excluding uppercase of SI(m, u, n, p) is considered valid.
132
- /// - Singular: BTC, mBTC, uBTC, nBTC, pBTC
133
- /// - Plural or singular: sat, satoshi, bit, msat
113
+ /// # Accepted Denominations
134
114
///
135
- /// Due to ambiguity between mega and milli, pico and peta we prohibit usage of leading capital 'M', 'P'.
115
+ /// All upper or lower case, excluding SI prefix (c, m, u) which must be lower case.
116
+ /// - Singular: BTC, cBTC, mBTC, uBTC
117
+ /// - Plural or singular: sat, satoshi, bit
118
+ ///
119
+ /// Due to ambiguity between mega and milli we prohibit usage of leading capital 'M'.
136
120
fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
137
121
use self :: ParseDenominationError :: * ;
138
122
@@ -2033,7 +2017,7 @@ mod tests {
2033
2017
#[ test]
2034
2018
#[ cfg( feature = "alloc" ) ]
2035
2019
fn from_str_zero ( ) {
2036
- let denoms = [ "BTC" , "mBTC" , "uBTC" , "nBTC" , "pBTC" , " bits", "sats" , "msats "] ;
2020
+ let denoms = [ "BTC" , "mBTC" , "uBTC" , "bits" , "sats" ] ;
2037
2021
for denom in denoms {
2038
2022
for v in & [ "0" , "000" ] {
2039
2023
let s = format ! ( "{} {}" , v, denom) ;
@@ -2173,13 +2157,10 @@ mod tests {
2173
2157
assert_eq ! ( f( 11.22 , D :: Bitcoin ) , Ok ( sat( 1122000000 ) ) ) ;
2174
2158
assert_eq ! ( sf( -11.22 , D :: MilliBitcoin ) , Ok ( ssat( -1122000 ) ) ) ;
2175
2159
assert_eq ! ( f( 11.22 , D :: Bit ) , Ok ( sat( 1122 ) ) ) ;
2176
- assert_eq ! ( sf( -1000.0 , D :: MilliSatoshi ) , Ok ( ssat( -1 ) ) ) ;
2177
2160
assert_eq ! ( f( 0.0001234 , D :: Bitcoin ) , Ok ( sat( 12340 ) ) ) ;
2178
2161
assert_eq ! ( sf( -0.00012345 , D :: Bitcoin ) , Ok ( ssat( -12345 ) ) ) ;
2179
2162
2180
- assert_eq ! ( f( -100.0 , D :: MilliSatoshi ) , Err ( OutOfRangeError :: negative( ) . into( ) ) ) ;
2181
2163
assert_eq ! ( f( 11.22 , D :: Satoshi ) , Err ( TooPreciseError { position: 3 } . into( ) ) ) ;
2182
- assert_eq ! ( sf( -100.0 , D :: MilliSatoshi ) , Err ( TooPreciseError { position: 1 } . into( ) ) ) ;
2183
2164
assert_eq ! ( f( 42.123456781 , D :: Bitcoin ) , Err ( TooPreciseError { position: 11 } . into( ) ) ) ;
2184
2165
assert_eq ! ( sf( -184467440738.0 , D :: Bitcoin ) , Err ( OutOfRangeError :: too_small( ) . into( ) ) ) ;
2185
2166
assert_eq ! (
@@ -2204,7 +2185,6 @@ mod tests {
2204
2185
assert_eq ! ( btc( 2.5 ) . to_float_in( D :: Bitcoin ) , 2.5 ) ;
2205
2186
assert_eq ! ( btc( -2.5 ) . to_float_in( D :: MilliBitcoin ) , -2500.0 ) ;
2206
2187
assert_eq ! ( btc( 2.5 ) . to_float_in( D :: Satoshi ) , 250000000.0 ) ;
2207
- assert_eq ! ( btc( -2.5 ) . to_float_in( D :: MilliSatoshi ) , -250000000000.0 ) ;
2208
2188
2209
2189
let btc = move |f| Amount :: from_btc ( f) . unwrap ( ) ;
2210
2190
assert_eq ! ( & btc( 0.0012 ) . to_float_in( D :: Bitcoin ) . to_string( ) , "0.0012" )
@@ -2216,7 +2196,6 @@ mod tests {
2216
2196
use super :: ParseAmountError as E ;
2217
2197
let btc = Denomination :: Bitcoin ;
2218
2198
let sat = Denomination :: Satoshi ;
2219
- let msat = Denomination :: MilliSatoshi ;
2220
2199
let p = Amount :: from_str_in;
2221
2200
let sp = SignedAmount :: from_str_in;
2222
2201
@@ -2249,15 +2228,11 @@ mod tests {
2249
2228
#[ cfg( feature = "alloc" ) ]
2250
2229
assert_eq ! ( p( & more_than_max, btc) , Err ( OutOfRangeError :: too_big( false ) . into( ) ) ) ;
2251
2230
assert_eq ! ( p( "0.000000042" , btc) , Err ( TooPreciseError { position: 10 } . into( ) ) ) ;
2252
- assert_eq ! ( p( "999.0000000" , msat) , Err ( TooPreciseError { position: 0 } . into( ) ) ) ;
2253
- assert_eq ! ( p( "1.0000000" , msat) , Err ( TooPreciseError { position: 0 } . into( ) ) ) ;
2254
- assert_eq ! ( p( "1.1" , msat) , Err ( TooPreciseError { position: 0 } . into( ) ) ) ;
2255
- assert_eq ! ( p( "1000.1" , msat) , Err ( TooPreciseError { position: 5 } . into( ) ) ) ;
2256
- assert_eq ! ( p( "1001.0000000" , msat) , Err ( TooPreciseError { position: 3 } . into( ) ) ) ;
2257
- assert_eq ! ( p( "1000.0000001" , msat) , Err ( TooPreciseError { position: 11 } . into( ) ) ) ;
2258
- assert_eq ! ( p( "1000.1000000" , msat) , Err ( TooPreciseError { position: 5 } . into( ) ) ) ;
2259
- assert_eq ! ( p( "1100.0000000" , msat) , Err ( TooPreciseError { position: 1 } . into( ) ) ) ;
2260
- assert_eq ! ( p( "10001.0000000" , msat) , Err ( TooPreciseError { position: 4 } . into( ) ) ) ;
2231
+ assert_eq ! ( p( "1.0000000" , sat) , Ok ( Amount :: from_sat( 1 ) ) ) ;
2232
+ assert_eq ! ( p( "1.1" , sat) , Err ( TooPreciseError { position: 2 } . into( ) ) ) ;
2233
+ assert_eq ! ( p( "1000.1" , sat) , Err ( TooPreciseError { position: 5 } . into( ) ) ) ;
2234
+ assert_eq ! ( p( "1001.0000000" , sat) , Ok ( Amount :: from_sat( 1001 ) ) ) ;
2235
+ assert_eq ! ( p( "1000.0000001" , sat) , Err ( TooPreciseError { position: 11 } . into( ) ) ) ;
2261
2236
2262
2237
assert_eq ! ( p( "1" , btc) , Ok ( Amount :: from_sat( 1_000_000_00 ) ) ) ;
2263
2238
assert_eq ! ( sp( "-.5" , btc) , Ok ( SignedAmount :: from_sat( -500_000_00 ) ) ) ;
@@ -2273,8 +2248,6 @@ mod tests {
2273
2248
p( "12345678901.12345678" , btc) ,
2274
2249
Ok ( Amount :: from_sat( 12_345_678_901__123_456_78 ) )
2275
2250
) ;
2276
- assert_eq ! ( p( "1000.0" , msat) , Ok ( Amount :: from_sat( 1 ) ) ) ;
2277
- assert_eq ! ( p( "1000.000000000000000000000000000" , msat) , Ok ( Amount :: from_sat( 1 ) ) ) ;
2278
2251
2279
2252
// make sure satoshi > i64::MAX is checked.
2280
2253
#[ cfg( feature = "alloc" ) ]
@@ -2287,10 +2260,6 @@ mod tests {
2287
2260
assert ! ( Amount :: from_str_in( & ( amount + Amount ( 1 ) ) . to_string_in( sat) , sat) . is_ok( ) ) ;
2288
2261
}
2289
2262
2290
- assert_eq ! (
2291
- p( "12.000" , Denomination :: MilliSatoshi ) ,
2292
- Err ( TooPreciseError { position: 0 } . into( ) )
2293
- ) ;
2294
2263
// exactly 50 chars.
2295
2264
assert_eq ! (
2296
2265
p( "100000000000000.0000000000000000000000000000000000" , Denomination :: Bitcoin ) ,
@@ -2315,7 +2284,6 @@ mod tests {
2315
2284
assert_eq ! ( SignedAmount :: from_sat( -42 ) . to_string_in( D :: Bitcoin ) , "-0.00000042" ) ;
2316
2285
2317
2286
assert_eq ! ( Amount :: ONE_BTC . to_string_with_denomination( D :: Bitcoin ) , "1 BTC" ) ;
2318
- assert_eq ! ( Amount :: ONE_SAT . to_string_with_denomination( D :: MilliSatoshi ) , "1000 msat" ) ;
2319
2287
assert_eq ! (
2320
2288
SignedAmount :: ONE_BTC . to_string_with_denomination( D :: Satoshi ) ,
2321
2289
"100000000 satoshi"
@@ -2499,19 +2467,6 @@ mod tests {
2499
2467
btc_check_fmt_non_negative_show_denom_align_2, 1 , "{:^16}" , " 0.00000001" ;
2500
2468
}
2501
2469
2502
- check_format_non_negative ! {
2503
- MilliSatoshi ;
2504
- msat_check_fmt_non_negative_0, 0 , "{}" , "0" ;
2505
- msat_check_fmt_non_negative_1, 1 , "{}" , "1000" ;
2506
- msat_check_fmt_non_negative_2, 1 , "{:5}" , " 1000" ;
2507
- msat_check_fmt_non_negative_3, 1 , "{:05}" , "01000" ;
2508
- msat_check_fmt_non_negative_4, 1 , "{:.1}" , "1000.0" ;
2509
- msat_check_fmt_non_negative_5, 1 , "{:6.1}" , "1000.0" ;
2510
- msat_check_fmt_non_negative_6, 1 , "{:06.1}" , "1000.0" ;
2511
- msat_check_fmt_non_negative_7, 1 , "{:7.1}" , " 1000.0" ;
2512
- msat_check_fmt_non_negative_8, 1 , "{:07.1}" , "01000.0" ;
2513
- }
2514
-
2515
2470
#[ test]
2516
2471
fn test_unsigned_signed_conversion ( ) {
2517
2472
let sa = SignedAmount :: from_sat;
@@ -2617,10 +2572,6 @@ mod tests {
2617
2572
assert_eq ! ( "-5" , SignedAmount :: from_sat( -5 ) . to_string_in( D :: Satoshi ) ) ;
2618
2573
assert_eq ! ( "0.1" , Amount :: from_sat( 100_000_00 ) . to_string_in( D :: Bitcoin ) ) ;
2619
2574
assert_eq ! ( "-100" , SignedAmount :: from_sat( -10_000 ) . to_string_in( D :: Bit ) ) ;
2620
- assert_eq ! ( "2535830" , Amount :: from_sat( 253583 ) . to_string_in( D :: NanoBitcoin ) ) ;
2621
- assert_eq ! ( "-100000" , SignedAmount :: from_sat( -10_000 ) . to_string_in( D :: NanoBitcoin ) ) ;
2622
- assert_eq ! ( "2535830000" , Amount :: from_sat( 253583 ) . to_string_in( D :: PicoBitcoin ) ) ;
2623
- assert_eq ! ( "-100000000" , SignedAmount :: from_sat( -10_000 ) . to_string_in( D :: PicoBitcoin ) ) ;
2624
2575
2625
2576
assert_eq ! ( "0.50" , format!( "{:.2}" , Amount :: from_sat( 50 ) . display_in( D :: Bit ) ) ) ;
2626
2577
assert_eq ! ( "-0.50" , format!( "{:.2}" , SignedAmount :: from_sat( -50 ) . display_in( D :: Bit ) ) ) ;
@@ -2661,31 +2612,6 @@ mod tests {
2661
2612
Err ( OutOfRangeError :: too_small( ) . into( ) )
2662
2613
) ;
2663
2614
2664
- assert_eq ! (
2665
- sa_str( & sa_sat( -1 ) . to_string_in( D :: NanoBitcoin ) , D :: NanoBitcoin ) ,
2666
- Ok ( sa_sat( -1 ) )
2667
- ) ;
2668
- assert_eq ! (
2669
- sa_str( & sa_sat( i64 :: MAX ) . to_string_in( D :: Satoshi ) , D :: NanoBitcoin ) ,
2670
- Err ( TooPreciseError { position: 18 } . into( ) )
2671
- ) ;
2672
- assert_eq ! (
2673
- sa_str( & sa_sat( i64 :: MIN ) . to_string_in( D :: Satoshi ) , D :: NanoBitcoin ) ,
2674
- Err ( TooPreciseError { position: 19 } . into( ) )
2675
- ) ;
2676
-
2677
- assert_eq ! (
2678
- sa_str( & sa_sat( -1 ) . to_string_in( D :: PicoBitcoin ) , D :: PicoBitcoin ) ,
2679
- Ok ( sa_sat( -1 ) )
2680
- ) ;
2681
- assert_eq ! (
2682
- sa_str( & sa_sat( i64 :: MAX ) . to_string_in( D :: Satoshi ) , D :: PicoBitcoin ) ,
2683
- Err ( TooPreciseError { position: 18 } . into( ) )
2684
- ) ;
2685
- assert_eq ! (
2686
- sa_str( & sa_sat( i64 :: MIN ) . to_string_in( D :: Satoshi ) , D :: PicoBitcoin ) ,
2687
- Err ( TooPreciseError { position: 19 } . into( ) )
2688
- ) ;
2689
2615
}
2690
2616
2691
2617
#[ cfg( feature = "alloc" ) ]
@@ -2702,9 +2628,6 @@ mod tests {
2702
2628
assert_eq ! ( Amount :: from_str( & denom( amt, D :: MicroBitcoin ) ) , Ok ( amt) ) ;
2703
2629
assert_eq ! ( Amount :: from_str( & denom( amt, D :: Bit ) ) , Ok ( amt) ) ;
2704
2630
assert_eq ! ( Amount :: from_str( & denom( amt, D :: Satoshi ) ) , Ok ( amt) ) ;
2705
- assert_eq ! ( Amount :: from_str( & denom( amt, D :: NanoBitcoin ) ) , Ok ( amt) ) ;
2706
- assert_eq ! ( Amount :: from_str( & denom( amt, D :: MilliSatoshi ) ) , Ok ( amt) ) ;
2707
- assert_eq ! ( Amount :: from_str( & denom( amt, D :: PicoBitcoin ) ) , Ok ( amt) ) ;
2708
2631
2709
2632
assert_eq ! (
2710
2633
Amount :: from_str( "42 satoshi BTC" ) ,
@@ -2918,7 +2841,7 @@ mod tests {
2918
2841
// Non-exhaustive list of valid forms.
2919
2842
let valid = [
2920
2843
"BTC" , "btc" , "mBTC" , "mbtc" , "uBTC" , "ubtc" , "SATOSHI" , "satoshi" , "SATOSHIS" ,
2921
- "satoshis" , "SAT" , "sat" , "SATS" , "sats" , "bit" , "bits" , "nBTC" , "pBTC" ,
2844
+ "satoshis" , "SAT" , "sat" , "SATS" , "sats" , "bit" , "bits" ,
2922
2845
] ;
2923
2846
for denom in valid. iter ( ) {
2924
2847
assert ! ( Denomination :: from_str( denom) . is_ok( ) ) ;
@@ -2927,7 +2850,7 @@ mod tests {
2927
2850
2928
2851
#[ test]
2929
2852
fn disallow_confusing_forms ( ) {
2930
- let confusing = [ "Msat " , "Msats " , "MSAT " , "MSATS " , "MSat " , "MSats" , "MBTC" , "Mbtc" , "PBTC "] ;
2853
+ let confusing = [ "CBTC " , "Cbtc " , "MBTC " , "Mbtc " , "UBTC " , "Ubtc " ] ;
2931
2854
for denom in confusing. iter ( ) {
2932
2855
match Denomination :: from_str ( denom) {
2933
2856
Ok ( _) => panic ! ( "from_str should error for {}" , denom) ,
@@ -2940,7 +2863,7 @@ mod tests {
2940
2863
#[ test]
2941
2864
fn disallow_unknown_denomination ( ) {
2942
2865
// Non-exhaustive list of unknown forms.
2943
- let unknown = [ "NBTC" , "UBTC" , " ABC", "abc" , "cBtC " , "Sat" , "Sats "] ;
2866
+ let unknown = [ "NBTC" , "ABC" , "abc" , "mSat " , "msat " ] ;
2944
2867
for denom in unknown. iter ( ) {
2945
2868
match Denomination :: from_str ( denom) {
2946
2869
Ok ( _) => panic ! ( "from_str should error for {}" , denom) ,
0 commit comments