@@ -145,8 +145,12 @@ mod std_impl {
145
145
fn decode ( buf : & mut & [ u8 ] ) -> Result < Self > {
146
146
let bytes = Header :: decode_bytes ( buf, false ) ?;
147
147
match bytes. len ( ) {
148
- 4 => static_left_pad ( bytes) . map ( |octets| Self :: V4 ( Ipv4Addr :: from ( octets) ) ) ,
149
- 16 => static_left_pad ( bytes) . map ( |octets| Self :: V6 ( Ipv6Addr :: from ( octets) ) ) ,
148
+ 4 => Ok ( Self :: V4 ( Ipv4Addr :: from (
149
+ slice_to_array :: < 4 > ( bytes) . expect ( "infallible" ) ,
150
+ ) ) ) ,
151
+ 16 => Ok ( Self :: V6 ( Ipv6Addr :: from (
152
+ slice_to_array :: < 16 > ( bytes) . expect ( "infallible" ) ,
153
+ ) ) ) ,
150
154
_ => Err ( Error :: UnexpectedLength ) ,
151
155
}
152
156
}
@@ -156,15 +160,15 @@ mod std_impl {
156
160
#[ inline]
157
161
fn decode ( buf : & mut & [ u8 ] ) -> Result < Self > {
158
162
let bytes = Header :: decode_bytes ( buf, false ) ?;
159
- static_left_pad :: < 4 > ( bytes) . map ( Self :: from)
163
+ slice_to_array :: < 4 > ( bytes) . map ( Self :: from)
160
164
}
161
165
}
162
166
163
167
impl Decodable for Ipv6Addr {
164
168
#[ inline]
165
169
fn decode ( buf : & mut & [ u8 ] ) -> Result < Self > {
166
170
let bytes = Header :: decode_bytes ( buf, false ) ?;
167
- static_left_pad :: < 16 > ( bytes) . map ( Self :: from)
171
+ slice_to_array :: < 16 > ( bytes) . map ( Self :: from)
168
172
}
169
173
}
170
174
}
@@ -195,33 +199,43 @@ pub(crate) fn static_left_pad<const N: usize>(data: &[u8]) -> Result<[u8; N]> {
195
199
Ok ( v)
196
200
}
197
201
202
+ #[ cfg( feature = "std" ) ]
203
+ #[ inline]
204
+ fn slice_to_array < const N : usize > ( slice : & [ u8 ] ) -> Result < [ u8 ; N ] > {
205
+ slice. try_into ( ) . map_err ( |_| Error :: UnexpectedLength )
206
+ }
207
+
198
208
#[ cfg( test) ]
199
209
mod tests {
200
210
use super :: * ;
211
+ use crate :: Encodable ;
201
212
use alloc:: { string:: String , vec:: Vec } ;
202
213
use core:: fmt:: Debug ;
203
214
use hex_literal:: hex;
204
215
205
216
fn check_decode < ' a , T , IT > ( fixtures : IT )
206
217
where
207
- T : Decodable + PartialEq + Debug ,
218
+ T : Encodable + Decodable + PartialEq + Debug ,
208
219
IT : IntoIterator < Item = ( Result < T > , & ' a [ u8 ] ) > ,
209
220
{
210
221
for ( expected, mut input) in fixtures {
211
- assert_eq ! ( T :: decode( & mut input) , expected) ;
212
- if expected. is_ok ( ) {
213
- assert_eq ! ( input, & [ ] ) ;
222
+ if let Ok ( expected) = & expected {
223
+ assert_eq ! ( crate :: encode( expected) , input, "{expected:?}" ) ;
214
224
}
215
- }
216
- }
217
225
218
- fn check_decode_list < T , IT > ( fixtures : IT )
219
- where
220
- T : Decodable + PartialEq + Debug ,
221
- IT : IntoIterator < Item = ( Result < Vec < T > > , & ' static [ u8 ] ) > ,
222
- {
223
- for ( expected, mut input) in fixtures {
224
- assert_eq ! ( Vec :: <T >:: decode( & mut input) , expected) ;
226
+ let orig = input;
227
+ assert_eq ! (
228
+ T :: decode( & mut input) ,
229
+ expected,
230
+ "input: {}{}" ,
231
+ hex:: encode( orig) ,
232
+ if let Ok ( expected) = & expected {
233
+ format!( "; expected: {}" , hex:: encode( crate :: encode( expected) ) )
234
+ } else {
235
+ String :: new( )
236
+ }
237
+ ) ;
238
+
225
239
if expected. is_ok ( ) {
226
240
assert_eq ! ( input, & [ ] ) ;
227
241
}
@@ -230,7 +244,7 @@ mod tests {
230
244
231
245
#[ test]
232
246
fn rlp_strings ( ) {
233
- check_decode :: < Bytes , _ > ( vec ! [
247
+ check_decode :: < Bytes , _ > ( [
234
248
( Ok ( hex ! ( "00" ) [ ..] . to_vec ( ) . into ( ) ) , & hex ! ( "00" ) [ ..] ) ,
235
249
(
236
250
Ok ( hex ! ( "6f62636465666768696a6b6c6d" ) [ ..] . to_vec ( ) . into ( ) ) ,
@@ -249,15 +263,15 @@ mod tests {
249
263
250
264
let mut b = BytesMut :: new ( ) ;
251
265
"test smol str" . to_string ( ) . encode ( & mut b) ;
252
- check_decode :: < SmolStr , _ > ( vec ! [
266
+ check_decode :: < SmolStr , _ > ( [
253
267
( Ok ( SmolStr :: new ( "test smol str" ) ) , b. as_ref ( ) ) ,
254
268
( Err ( Error :: UnexpectedList ) , & hex ! ( "C0" ) [ ..] ) ,
255
269
] )
256
270
}
257
271
258
272
#[ test]
259
273
fn rlp_fixed_length ( ) {
260
- check_decode ( vec ! [
274
+ check_decode ( [
261
275
(
262
276
Ok ( hex ! ( "6f62636465666768696a6b6c6d" ) ) ,
263
277
& hex ! ( "8D6F62636465666768696A6B6C6D" ) [ ..] ,
@@ -275,7 +289,7 @@ mod tests {
275
289
276
290
#[ test]
277
291
fn rlp_u64 ( ) {
278
- check_decode ( vec ! [
292
+ check_decode ( [
279
293
( Ok ( 9_u64 ) , & hex ! ( "09" ) [ ..] ) ,
280
294
( Ok ( 0_u64 ) , & hex ! ( "80" ) [ ..] ) ,
281
295
( Ok ( 0x0505_u64 ) , & hex ! ( "820505" ) [ ..] ) ,
@@ -299,7 +313,7 @@ mod tests {
299
313
300
314
#[ test]
301
315
fn rlp_vectors ( ) {
302
- check_decode_list ( vec ! [
316
+ check_decode :: < Vec < u64 > , _ > ( [
303
317
( Ok ( vec ! [ ] ) , & hex ! ( "C0" ) [ ..] ) ,
304
318
(
305
319
Ok ( vec ! [ 0xBBCCB5_u64 , 0xFFC0B5_u64 ] ) ,
@@ -308,34 +322,51 @@ mod tests {
308
322
] )
309
323
}
310
324
325
+ #[ cfg( feature = "std" ) ]
326
+ #[ test]
327
+ fn rlp_ip ( ) {
328
+ use std:: net:: { IpAddr , Ipv4Addr , Ipv6Addr } ;
329
+
330
+ let localhost4 = Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) ;
331
+ let localhost6 = localhost4. to_ipv6_mapped ( ) ;
332
+ let expected4 = & hex ! ( "847F000001" ) [ ..] ;
333
+ let expected6 = & hex ! ( "9000000000000000000000ffff7f000001" ) [ ..] ;
334
+ check_decode :: < Ipv4Addr , _ > ( [ ( Ok ( localhost4) , expected4) ] ) ;
335
+ check_decode :: < Ipv6Addr , _ > ( [ ( Ok ( localhost6) , expected6) ] ) ;
336
+ check_decode :: < IpAddr , _ > ( [
337
+ ( Ok ( IpAddr :: V4 ( localhost4) ) , expected4) ,
338
+ ( Ok ( IpAddr :: V6 ( localhost6) ) , expected6) ,
339
+ ] ) ;
340
+ }
341
+
311
342
#[ test]
312
343
fn malformed_rlp ( ) {
313
- check_decode :: < Bytes , _ > ( vec ! [
344
+ check_decode :: < Bytes , _ > ( [
314
345
( Err ( Error :: InputTooShort ) , & hex ! ( "C1" ) [ ..] ) ,
315
346
( Err ( Error :: InputTooShort ) , & hex ! ( "D7" ) [ ..] ) ,
316
347
] ) ;
317
- check_decode :: < [ u8 ; 5 ] , _ > ( vec ! [
348
+ check_decode :: < [ u8 ; 5 ] , _ > ( [
318
349
( Err ( Error :: InputTooShort ) , & hex ! ( "C1" ) [ ..] ) ,
319
350
( Err ( Error :: InputTooShort ) , & hex ! ( "D7" ) [ ..] ) ,
320
351
] ) ;
321
352
#[ cfg( feature = "std" ) ]
322
- check_decode :: < std:: net:: IpAddr , _ > ( vec ! [
353
+ check_decode :: < std:: net:: IpAddr , _ > ( [
323
354
( Err ( Error :: InputTooShort ) , & hex ! ( "C1" ) [ ..] ) ,
324
355
( Err ( Error :: InputTooShort ) , & hex ! ( "D7" ) [ ..] ) ,
325
356
] ) ;
326
- check_decode :: < Vec < u8 > , _ > ( vec ! [
357
+ check_decode :: < Vec < u8 > , _ > ( [
327
358
( Err ( Error :: InputTooShort ) , & hex ! ( "C1" ) [ ..] ) ,
328
359
( Err ( Error :: InputTooShort ) , & hex ! ( "D7" ) [ ..] ) ,
329
360
] ) ;
330
- check_decode :: < String , _ > ( vec ! [
361
+ check_decode :: < String , _ > ( [
331
362
( Err ( Error :: InputTooShort ) , & hex ! ( "C1" ) [ ..] ) ,
332
363
( Err ( Error :: InputTooShort ) , & hex ! ( "D7" ) [ ..] ) ,
333
364
] ) ;
334
- check_decode :: < String , _ > ( vec ! [
365
+ check_decode :: < String , _ > ( [
335
366
( Err ( Error :: InputTooShort ) , & hex ! ( "C1" ) [ ..] ) ,
336
367
( Err ( Error :: InputTooShort ) , & hex ! ( "D7" ) [ ..] ) ,
337
368
] ) ;
338
- check_decode :: < u8 , _ > ( vec ! [ ( Err ( Error :: InputTooShort ) , & hex!( "82" ) [ ..] ) ] ) ;
339
- check_decode :: < u64 , _ > ( vec ! [ ( Err ( Error :: InputTooShort ) , & hex!( "82" ) [ ..] ) ] ) ;
369
+ check_decode :: < u8 , _ > ( [ ( Err ( Error :: InputTooShort ) , & hex ! ( "82" ) [ ..] ) ] ) ;
370
+ check_decode :: < u64 , _ > ( [ ( Err ( Error :: InputTooShort ) , & hex ! ( "82" ) [ ..] ) ] ) ;
340
371
}
341
372
}
0 commit comments