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
|
//! 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.
|
//! 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;
|
use crate::mem::transmute;
|
||||||
|
|
||||||
/// One of the 128 Unicode characters from U+0000 through U+007F,
|
/// 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")]
|
#[unstable(feature = "ascii_char", issue = "110998")]
|
||||||
impl fmt::Debug for AsciiChar {
|
impl fmt::Debug for AsciiChar {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
#[inline]
|
use AsciiChar::{Apostrophe, Null, ReverseSolidus as Backslash};
|
||||||
fn backslash(a: AsciiChar) -> ([AsciiChar; 4], u8) {
|
|
||||||
([AsciiChar::ReverseSolidus, a, AsciiChar::Null, AsciiChar::Null], 2)
|
fn backslash(a: AsciiChar) -> ([AsciiChar; 6], usize) {
|
||||||
|
([Apostrophe, Backslash, a, Apostrophe, Null, Null], 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
let (buf, len) = match self {
|
let (buf, len) = match self {
|
||||||
@ -595,24 +596,17 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|||||||
AsciiChar::LineFeed => backslash(AsciiChar::SmallN),
|
AsciiChar::LineFeed => backslash(AsciiChar::SmallN),
|
||||||
AsciiChar::ReverseSolidus => backslash(AsciiChar::ReverseSolidus),
|
AsciiChar::ReverseSolidus => backslash(AsciiChar::ReverseSolidus),
|
||||||
AsciiChar::Apostrophe => backslash(AsciiChar::Apostrophe),
|
AsciiChar::Apostrophe => backslash(AsciiChar::Apostrophe),
|
||||||
_ => {
|
_ if self.to_u8().is_ascii_control() => {
|
||||||
let byte = self.to_u8();
|
|
||||||
if !byte.is_ascii_control() {
|
|
||||||
([*self, AsciiChar::Null, AsciiChar::Null, AsciiChar::Null], 1)
|
|
||||||
} else {
|
|
||||||
const HEX_DIGITS: [AsciiChar; 16] = *b"0123456789abcdef".as_ascii().unwrap();
|
const HEX_DIGITS: [AsciiChar; 16] = *b"0123456789abcdef".as_ascii().unwrap();
|
||||||
|
|
||||||
|
let byte = self.to_u8();
|
||||||
let hi = HEX_DIGITS[usize::from(byte >> 4)];
|
let hi = HEX_DIGITS[usize::from(byte >> 4)];
|
||||||
let lo = HEX_DIGITS[usize::from(byte & 0xf)];
|
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('\'')?;
|
f.write_str(buf[..len].as_str())
|
||||||
for byte in &buf[..len as usize] {
|
|
||||||
f.write_str(byte.as_str())?;
|
|
||||||
}
|
|
||||||
f.write_char('\'')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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 any;
|
||||||
mod array;
|
mod array;
|
||||||
mod ascii;
|
mod ascii;
|
||||||
|
mod ascii_char;
|
||||||
mod asserting;
|
mod asserting;
|
||||||
mod async_iter;
|
mod async_iter;
|
||||||
mod atomic;
|
mod atomic;
|
||||||
|
Loading…
Reference in New Issue
Block a user