@@ -31,12 +31,18 @@ mod errors {
31
31
#[ derive( Debug ) ]
32
32
pub struct FromFieldElementError ;
33
33
34
+ #[ derive( Debug ) ]
35
+ pub struct FromBytesSliceError ;
36
+
34
37
#[ cfg( feature = "std" ) ]
35
38
impl std:: error:: Error for FromHexError { }
36
39
37
40
#[ cfg( feature = "std" ) ]
38
41
impl std:: error:: Error for FromFieldElementError { }
39
42
43
+ #[ cfg( feature = "std" ) ]
44
+ impl std:: error:: Error for FromBytesSliceError { }
45
+
40
46
impl Display for FromHexError {
41
47
fn fmt ( & self , f : & mut Formatter < ' _ > ) -> Result {
42
48
match self {
@@ -55,8 +61,14 @@ mod errors {
55
61
write ! ( f, "FieldElement value out of range" )
56
62
}
57
63
}
64
+
65
+ impl Display for FromBytesSliceError {
66
+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> Result {
67
+ write ! ( f, "invalid slice for ETH address" )
68
+ }
69
+ }
58
70
}
59
- pub use errors:: { FromFieldElementError , FromHexError } ;
71
+ pub use errors:: { FromBytesSliceError , FromFieldElementError , FromHexError } ;
60
72
61
73
impl EthAddress {
62
74
pub fn from_hex ( hex : & str ) -> Result < Self , FromHexError > {
@@ -156,3 +168,66 @@ impl From<EthAddress> for FieldElement {
156
168
FieldElement :: from_byte_slice_be ( & value. inner ) . unwrap ( )
157
169
}
158
170
}
171
+
172
+ impl TryFrom < & [ u8 ] > for EthAddress {
173
+ type Error = FromBytesSliceError ;
174
+
175
+ fn try_from ( value : & [ u8 ] ) -> Result < Self , Self :: Error > {
176
+ if value. len ( ) != 20 {
177
+ Err ( FromBytesSliceError )
178
+ } else {
179
+ // Safe to unwrap as we know length is 20.
180
+ Ok ( Self {
181
+ inner : value. try_into ( ) . unwrap ( ) ,
182
+ } )
183
+ }
184
+ }
185
+ }
186
+
187
+ impl From < [ u8 ; 20 ] > for EthAddress {
188
+ fn from ( value : [ u8 ; 20 ] ) -> Self {
189
+ Self { inner : value }
190
+ }
191
+ }
192
+
193
+ #[ cfg( test) ]
194
+ mod tests {
195
+ use hex_literal:: hex;
196
+
197
+ use super :: EthAddress ;
198
+
199
+ #[ test]
200
+ #[ cfg_attr( target_arch = "wasm32" , wasm_bindgen_test:: wasm_bindgen_test) ]
201
+ fn test_eth_address_from_bytes_array ( ) {
202
+ let address_bytes: [ u8 ; 20 ] = hex ! ( "e7f1725e7734ce288f8367e1bb143e90bb3f0512" ) ;
203
+
204
+ let eth_address: EthAddress = address_bytes. into ( ) ;
205
+ assert_eq ! (
206
+ EthAddress :: from_hex( "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512" ) . unwrap( ) ,
207
+ eth_address
208
+ ) ;
209
+ }
210
+
211
+ #[ test]
212
+ #[ cfg_attr( target_arch = "wasm32" , wasm_bindgen_test:: wasm_bindgen_test) ]
213
+ fn test_eth_address_from_slice ( ) {
214
+ // address: e7f1725e7734ce288f8367e1bb143e90bb3f0512, inside a buffer with more data.
215
+ let buffer = hex ! ( "010203e7f1725e7734ce288f8367e1bb143e90bb3f0512" ) ;
216
+
217
+ let eth_address: EthAddress = ( & buffer[ 3 ..23 ] )
218
+ . try_into ( )
219
+ . expect ( "failed to get EthAddress from slice" ) ;
220
+ assert_eq ! (
221
+ EthAddress :: from_hex( "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512" ) . unwrap( ) ,
222
+ eth_address
223
+ ) ;
224
+ }
225
+
226
+ #[ test]
227
+ #[ should_panic( expected = "FromBytesSliceError" ) ]
228
+ fn test_eth_address_from_slice_invalid_slice ( ) {
229
+ let buffer: Vec < u8 > = vec ! [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ;
230
+
231
+ EthAddress :: try_from ( & buffer[ 0 ..4 ] ) . unwrap ( ) ;
232
+ }
233
+ }
0 commit comments