@@ -7,21 +7,21 @@ use crate::ops::Range;
7
7
const HEX_DIGITS: [ascii::Char; 16] = *b"0123456789abcdef".as_ascii().unwrap();
8
8
9
9
#[inline]
10
- const fn backslash<const N: usize>(a: ascii::Char) -> ([ascii::Char; N], u8 ) {
10
+ const fn backslash<const N: usize>(a: ascii::Char) -> ([ascii::Char; N], Range<u8> ) {
11
11
const { assert!(N >= 2) };
12
12
13
13
let mut output = [ascii::Char::Null; N];
14
14
15
15
output[0] = ascii::Char::ReverseSolidus;
16
16
output[1] = a;
17
17
18
- (output, 2)
18
+ (output, 0.. 2)
19
19
}
20
20
21
21
/// Escapes an ASCII character.
22
22
///
23
23
/// Returns a buffer and the length of the escaped representation.
24
- const fn escape_ascii<const N: usize>(byte: u8) -> ([ascii::Char; N], u8 ) {
24
+ const fn escape_ascii<const N: usize>(byte: u8) -> ([ascii::Char; N], Range<u8> ) {
25
25
const { assert!(N >= 4) };
26
26
27
27
match byte {
@@ -38,7 +38,7 @@ const fn escape_ascii<const N: usize>(byte: u8) -> ([ascii::Char; N], u8) {
38
38
&& !byte.is_ascii_control()
39
39
{
40
40
output[0] = c;
41
- (output, 1)
41
+ (output, 0.. 1)
42
42
} else {
43
43
let hi = HEX_DIGITS[(byte >> 4) as usize];
44
44
let lo = HEX_DIGITS[(byte & 0xf) as usize];
@@ -48,7 +48,7 @@ const fn escape_ascii<const N: usize>(byte: u8) -> ([ascii::Char; N], u8) {
48
48
output[2] = hi;
49
49
output[3] = lo;
50
50
51
- (output, 4)
51
+ (output, 0.. 4)
52
52
}
53
53
}
54
54
}
@@ -57,34 +57,28 @@ const fn escape_ascii<const N: usize>(byte: u8) -> ([ascii::Char; N], u8) {
57
57
/// Escapes a character `\u{NNNN}` representation.
58
58
///
59
59
/// Returns a buffer and the length of the escaped representation.
60
- const fn escape_unicode<const N: usize>(c: char) -> ([ascii::Char; N], u8 ) {
61
- const { assert!(N >= 10) };
60
+ const fn escape_unicode<const N: usize>(c: char) -> ([ascii::Char; N], Range<u8> ) {
61
+ const { assert!(N >= 10 && N < u8::MAX as usize ) };
62
62
63
- let c = c as u32;
63
+ let c = u32::from(c) ;
64
64
65
65
// OR-ing `1` ensures that for `c == 0` the code computes that
66
66
// one digit should be printed.
67
- let u_len = (8 - (c | 1).leading_zeros() / 4) as usize;
68
-
69
- let closing_paren_offset = 3 + u_len;
67
+ let start = (c | 1).leading_zeros() as usize / 4 - 2;
70
68
71
69
let mut output = [ascii::Char::Null; N];
72
-
73
- output[0] = ascii::Char::ReverseSolidus;
74
- output[1] = ascii::Char::SmallU;
75
- output[2] = ascii::Char::LeftCurlyBracket;
76
-
77
- output[3 + u_len.saturating_sub(6)] = HEX_DIGITS[((c >> 20) & 0x0f) as usize];
78
- output[3 + u_len.saturating_sub(5)] = HEX_DIGITS[((c >> 16) & 0x0f) as usize];
79
- output[3 + u_len.saturating_sub(4)] = HEX_DIGITS[((c >> 12) & 0x0f) as usize];
80
- output[3 + u_len.saturating_sub(3)] = HEX_DIGITS[((c >> 8) & 0x0f) as usize];
81
- output[3 + u_len.saturating_sub(2)] = HEX_DIGITS[((c >> 4) & 0x0f) as usize];
82
- output[3 + u_len.saturating_sub(1)] = HEX_DIGITS[((c >> 0) & 0x0f) as usize];
83
-
84
- output[closing_paren_offset] = ascii::Char::RightCurlyBracket;
85
-
86
- let len = (closing_paren_offset + 1) as u8;
87
- (output, len)
70
+ output[3] = HEX_DIGITS[((c >> 20) & 15) as usize];
71
+ output[4] = HEX_DIGITS[((c >> 16) & 15) as usize];
72
+ output[5] = HEX_DIGITS[((c >> 12) & 15) as usize];
73
+ output[6] = HEX_DIGITS[((c >> 8) & 15) as usize];
74
+ output[7] = HEX_DIGITS[((c >> 4) & 15) as usize];
75
+ output[8] = HEX_DIGITS[((c >> 0) & 15) as usize];
76
+ output[9] = ascii::Char::RightCurlyBracket;
77
+ output[start + 0] = ascii::Char::ReverseSolidus;
78
+ output[start + 1] = ascii::Char::SmallU;
79
+ output[start + 2] = ascii::Char::LeftCurlyBracket;
80
+
81
+ (output, (start as u8)..(N as u8))
88
82
}
89
83
90
84
/// An iterator over an fixed-size array.
@@ -102,25 +96,26 @@ pub(crate) struct EscapeIterInner<const N: usize> {
102
96
103
97
impl<const N: usize> EscapeIterInner<N> {
104
98
pub const fn backslash(c: ascii::Char) -> Self {
105
- let (data, len ) = backslash(c);
106
- Self { data, alive: 0..len }
99
+ let (data, range ) = backslash(c);
100
+ Self { data, alive: range }
107
101
}
108
102
109
103
pub const fn ascii(c: u8) -> Self {
110
- let (data, len ) = escape_ascii(c);
111
- Self { data, alive: 0..len }
104
+ let (data, range ) = escape_ascii(c);
105
+ Self { data, alive: range }
112
106
}
113
107
114
108
pub const fn unicode(c: char) -> Self {
115
- let (data, len ) = escape_unicode(c);
116
- Self { data, alive: 0..len }
109
+ let (data, range ) = escape_unicode(c);
110
+ Self { data, alive: range }
117
111
}
118
112
119
113
#[inline]
120
114
pub const fn empty() -> Self {
121
115
Self { data: [ascii::Char::Null; N], alive: 0..0 }
122
116
}
123
117
118
+ #[inline]
124
119
pub fn as_ascii(&self) -> &[ascii::Char] {
125
120
// SAFETY: `self.alive` is guaranteed to be a valid range for indexing `self.data`.
126
121
unsafe {
0 commit comments