@@ -19,6 +19,7 @@ use {ArrayLength, GenericArray};
19
19
use core:: fmt;
20
20
use core:: ops:: Add ;
21
21
use core:: str;
22
+ use core:: cmp:: min;
22
23
use typenum:: * ;
23
24
24
25
static LOWER_CHARS : & ' static [ u8 ] = b"0123456789abcdef" ;
@@ -30,28 +31,32 @@ where
30
31
<T as Add < T > >:: Output : ArrayLength < u8 > ,
31
32
{
32
33
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
33
- let max_digits = f. precision ( ) . unwrap_or_else ( || self . len ( ) ) ;
34
+ let max_digits = f. precision ( ) . unwrap_or_else ( || self . len ( ) * 2 ) ;
35
+ let max_hex = ( max_digits >> 1 ) + ( max_digits & 1 ) ;
34
36
35
37
if T :: to_usize ( ) < 1024 {
36
38
// For small arrays use a stack allocated
37
39
// buffer of 2x number of bytes
38
40
let mut res = GenericArray :: < u8 , Sum < T , T > > :: default ( ) ;
39
41
40
- for ( i, c) in self . iter ( ) . take ( max_digits ) . enumerate ( ) {
42
+ for ( i, c) in self . iter ( ) . take ( max_hex ) . enumerate ( ) {
41
43
res[ i * 2 ] = LOWER_CHARS [ ( c >> 4 ) as usize ] ;
42
44
res[ i * 2 + 1 ] = LOWER_CHARS [ ( c & 0xF ) as usize ] ;
43
45
}
44
- f. write_str ( unsafe { str:: from_utf8_unchecked ( & res[ ..max_digits * 2 ] ) } ) ?;
46
+ f. write_str ( unsafe { str:: from_utf8_unchecked ( & res[ ..max_digits] ) } ) ?;
45
47
} else {
46
48
// For large array use chunks of up to 1024 bytes (2048 hex chars)
47
49
let mut buf = [ 0u8 ; 2048 ] ;
50
+ let mut digits_left = max_digits;
48
51
49
- for chunk in self [ ..max_digits ] . chunks ( 1024 ) {
52
+ for chunk in self [ ..max_hex ] . chunks ( 1024 ) {
50
53
for ( i, c) in chunk. iter ( ) . enumerate ( ) {
51
54
buf[ i * 2 ] = LOWER_CHARS [ ( c >> 4 ) as usize ] ;
52
55
buf[ i * 2 + 1 ] = LOWER_CHARS [ ( c & 0xF ) as usize ] ;
53
56
}
54
- f. write_str ( unsafe { str:: from_utf8_unchecked ( & buf[ ..chunk. len ( ) * 2 ] ) } ) ?;
57
+ let n = min ( chunk. len ( ) * 2 , digits_left) ;
58
+ f. write_str ( unsafe { str:: from_utf8_unchecked ( & buf[ ..n] ) } ) ?;
59
+ digits_left -= n;
55
60
}
56
61
}
57
62
Ok ( ( ) )
@@ -64,28 +69,32 @@ where
64
69
<T as Add < T > >:: Output : ArrayLength < u8 > ,
65
70
{
66
71
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
67
- let max_digits = f. precision ( ) . unwrap_or_else ( || self . len ( ) ) ;
72
+ let max_digits = f. precision ( ) . unwrap_or_else ( || self . len ( ) * 2 ) ;
73
+ let max_hex = ( max_digits >> 1 ) + ( max_digits & 1 ) ;
68
74
69
75
if T :: to_usize ( ) < 1024 {
70
76
// For small arrays use a stack allocated
71
77
// buffer of 2x number of bytes
72
78
let mut res = GenericArray :: < u8 , Sum < T , T > > :: default ( ) ;
73
79
74
- for ( i, c) in self . iter ( ) . take ( max_digits ) . enumerate ( ) {
80
+ for ( i, c) in self . iter ( ) . take ( max_hex ) . enumerate ( ) {
75
81
res[ i * 2 ] = UPPER_CHARS [ ( c >> 4 ) as usize ] ;
76
82
res[ i * 2 + 1 ] = UPPER_CHARS [ ( c & 0xF ) as usize ] ;
77
83
}
78
- f. write_str ( unsafe { str:: from_utf8_unchecked ( & res[ ..max_digits * 2 ] ) } ) ?;
84
+ f. write_str ( unsafe { str:: from_utf8_unchecked ( & res[ ..max_digits] ) } ) ?;
79
85
} else {
80
86
// For large array use chunks of up to 1024 bytes (2048 hex chars)
81
87
let mut buf = [ 0u8 ; 2048 ] ;
88
+ let mut digits_left = max_digits;
82
89
83
- for chunk in self [ ..max_digits ] . chunks ( 1024 ) {
90
+ for chunk in self [ ..max_hex ] . chunks ( 1024 ) {
84
91
for ( i, c) in chunk. iter ( ) . enumerate ( ) {
85
92
buf[ i * 2 ] = UPPER_CHARS [ ( c >> 4 ) as usize ] ;
86
93
buf[ i * 2 + 1 ] = UPPER_CHARS [ ( c & 0xF ) as usize ] ;
87
94
}
88
- f. write_str ( unsafe { str:: from_utf8_unchecked ( & buf[ ..chunk. len ( ) * 2 ] ) } ) ?;
95
+ let n = min ( chunk. len ( ) * 2 , digits_left) ;
96
+ f. write_str ( unsafe { str:: from_utf8_unchecked ( & buf[ ..n] ) } ) ?;
97
+ digits_left -= n;
89
98
}
90
99
}
91
100
Ok ( ( ) )
0 commit comments