@@ -8,6 +8,7 @@ use crate::{
8
8
use move_core_types:: account_address:: AccountAddress ;
9
9
use move_ir_types:: location:: * ;
10
10
use move_symbol_pool:: Symbol ;
11
+ use num_bigint:: BigUint ;
11
12
use petgraph:: { algo:: astar as petgraph_astar, graphmap:: DiGraphMap } ;
12
13
use std:: {
13
14
collections:: BTreeMap ,
@@ -61,6 +62,25 @@ pub fn parse_u128(s: &str) -> Result<(u128, NumberFormat), ParseIntError> {
61
62
Ok ( ( u128:: from_str_radix ( txt, base as u32 ) ?, base) )
62
63
}
63
64
65
+ // Parse an address from a decimal or hex encoding
66
+ pub fn parse_address ( s : & str ) -> Option < ( [ u8 ; AccountAddress :: LENGTH ] , NumberFormat ) > {
67
+ let ( txt, base) = determine_num_text_and_base ( s) ;
68
+ let parsed = BigUint :: parse_bytes (
69
+ txt. as_bytes ( ) ,
70
+ match base {
71
+ NumberFormat :: Hex => 16 ,
72
+ NumberFormat :: Decimal => 10 ,
73
+ } ,
74
+ ) ?;
75
+ let bytes = parsed. to_bytes_be ( ) ;
76
+ if bytes. len ( ) > AccountAddress :: LENGTH {
77
+ return None ;
78
+ }
79
+ let mut result = [ 0u8 ; AccountAddress :: LENGTH ] ;
80
+ result[ ( AccountAddress :: LENGTH - bytes. len ( ) ) ..] . clone_from_slice ( & bytes) ;
81
+ Some ( ( result, base) )
82
+ }
83
+
64
84
//**************************************************************************************************
65
85
// Address
66
86
//**************************************************************************************************
@@ -78,9 +98,7 @@ pub struct NumericalAddress {
78
98
impl NumericalAddress {
79
99
// bytes used for errors when an address is not known but is needed
80
100
pub const DEFAULT_ERROR_ADDRESS : Self = NumericalAddress {
81
- bytes : AccountAddress :: new ( [
82
- 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 1u8 ,
83
- ] ) ,
101
+ bytes : AccountAddress :: ONE ,
84
102
format : NumberFormat :: Hex ,
85
103
} ;
86
104
@@ -100,22 +118,22 @@ impl NumericalAddress {
100
118
}
101
119
102
120
pub fn parse_str ( s : & str ) -> Result < NumericalAddress , String > {
103
- let ( n, format) = match parse_u128 ( s) {
104
- Ok ( res) => res,
105
- Err ( _) => {
106
- // TODO the kind of error is in an unstable nightly API
107
- // But currently the only way this should fail is if the number is too long
108
- return Err (
121
+ match parse_address ( s) {
122
+ Some ( ( n, format) ) => Ok ( NumericalAddress {
123
+ bytes : AccountAddress :: new ( n) ,
124
+ format,
125
+ } ) ,
126
+ None =>
127
+ // TODO the kind of error is in an unstable nightly API
128
+ // But currently the only way this should fail is if the number is too long
129
+ {
130
+ Err ( format ! (
109
131
"Invalid address literal. The numeric value is too large. The maximum size is \
110
- 16 bytes"
111
- . to_owned ( ) ,
112
- ) ;
132
+ {} bytes",
133
+ AccountAddress :: LENGTH
134
+ ) )
113
135
}
114
- } ;
115
- Ok ( NumericalAddress {
116
- bytes : AccountAddress :: new ( n. to_be_bytes ( ) ) ,
117
- format,
118
- } )
136
+ }
119
137
}
120
138
}
121
139
@@ -129,7 +147,7 @@ impl fmt::Display for NumericalAddress {
129
147
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
130
148
match self . format {
131
149
NumberFormat :: Decimal => {
132
- let n = u128 :: from_be_bytes ( self . bytes . into_bytes ( ) ) ;
150
+ let n = BigUint :: from_bytes_be ( self . bytes . as_ref ( ) ) ;
133
151
write ! ( f, "{}" , n)
134
152
}
135
153
NumberFormat :: Hex => write ! ( f, "{:#X}" , self ) ,
0 commit comments