core: optimise Debug impl for ascii::Char
Rather than writing character at a time, optimise Debug implementation for core::ascii::Char such that it writes the entire representation as with a single write_str call. With that, add tests for Display and Debug implementations.
This commit is contained in:
parent
19ebdcedf1
commit
7d1de7f994
@ -3,7 +3,7 @@
|
||||
//! suggestions from rustc if you get anything slightly wrong in here, and overall
|
||||
//! helps with clarity as we're also referring to `char` intentionally in here.
|
||||
|
||||
use crate::fmt::{self, Write};
|
||||
use crate::fmt;
|
||||
use crate::mem::transmute;
|
||||
|
||||
/// One of the 128 Unicode characters from U+0000 through U+007F,
|
||||
@ -583,9 +583,10 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
#[unstable(feature = "ascii_char", issue = "110998")]
|
||||
impl fmt::Debug for AsciiChar {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
#[inline]
|
||||
fn backslash(a: AsciiChar) -> ([AsciiChar; 4], u8) {
|
||||
([AsciiChar::ReverseSolidus, a, AsciiChar::Null, AsciiChar::Null], 2)
|
||||
use AsciiChar::{Apostrophe, Null, ReverseSolidus as Backslash};
|
||||
|
||||
fn backslash(a: AsciiChar) -> ([AsciiChar; 6], usize) {
|
||||
([Apostrophe, Backslash, a, Apostrophe, Null, Null], 4)
|
||||
}
|
||||
|
||||
let (buf, len) = match self {
|
||||
@ -595,24 +596,17 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
AsciiChar::LineFeed => backslash(AsciiChar::SmallN),
|
||||
AsciiChar::ReverseSolidus => backslash(AsciiChar::ReverseSolidus),
|
||||
AsciiChar::Apostrophe => backslash(AsciiChar::Apostrophe),
|
||||
_ => {
|
||||
let byte = self.to_u8();
|
||||
if !byte.is_ascii_control() {
|
||||
([*self, AsciiChar::Null, AsciiChar::Null, AsciiChar::Null], 1)
|
||||
} else {
|
||||
_ if self.to_u8().is_ascii_control() => {
|
||||
const HEX_DIGITS: [AsciiChar; 16] = *b"0123456789abcdef".as_ascii().unwrap();
|
||||
|
||||
let byte = self.to_u8();
|
||||
let hi = HEX_DIGITS[usize::from(byte >> 4)];
|
||||
let lo = HEX_DIGITS[usize::from(byte & 0xf)];
|
||||
([AsciiChar::ReverseSolidus, AsciiChar::SmallX, hi, lo], 4)
|
||||
}
|
||||
([Apostrophe, Backslash, AsciiChar::SmallX, hi, lo, Apostrophe], 6)
|
||||
}
|
||||
_ => ([Apostrophe, *self, Apostrophe, Null, Null, Null], 3),
|
||||
};
|
||||
|
||||
f.write_char('\'')?;
|
||||
for byte in &buf[..len as usize] {
|
||||
f.write_str(byte.as_str())?;
|
||||
}
|
||||
f.write_char('\'')
|
||||
f.write_str(buf[..len].as_str())
|
||||
}
|
||||
}
|
||||
|
28
library/core/tests/ascii_char.rs
Normal file
28
library/core/tests/ascii_char.rs
Normal file
@ -0,0 +1,28 @@
|
||||
use core::ascii::Char;
|
||||
use core::fmt::Write;
|
||||
|
||||
/// Tests Display implementation for ascii::Char.
|
||||
#[test]
|
||||
fn test_display() {
|
||||
let want = (0..128u8).map(|b| b as char).collect::<String>();
|
||||
let mut got = String::with_capacity(128);
|
||||
for byte in 0..128 {
|
||||
write!(&mut got, "{}", Char::from_u8(byte).unwrap()).unwrap();
|
||||
}
|
||||
assert_eq!(want, got);
|
||||
}
|
||||
|
||||
/// Tests Debug implementation for ascii::Char.
|
||||
#[test]
|
||||
fn test_debug_control() {
|
||||
for byte in 0..128u8 {
|
||||
let mut want = format!("{:?}", byte as char);
|
||||
// `char` uses `'\u{#}'` representation where ascii::char uses `'\x##'`.
|
||||
// Transform former into the latter.
|
||||
if let Some(rest) = want.strip_prefix("'\\u{") {
|
||||
want = format!("'\\x{:0>2}'", rest.strip_suffix("}'").unwrap());
|
||||
}
|
||||
let chr = core::ascii::Char::from_u8(byte).unwrap();
|
||||
assert_eq!(want, format!("{chr:?}"), "byte: {byte}");
|
||||
}
|
||||
}
|
@ -122,6 +122,7 @@
|
||||
mod any;
|
||||
mod array;
|
||||
mod ascii;
|
||||
mod ascii_char;
|
||||
mod asserting;
|
||||
mod async_iter;
|
||||
mod atomic;
|
||||
|
Loading…
Reference in New Issue
Block a user