Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 13 additions & 19 deletions library/core/src/ascii/ascii_char.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -583,9 +583,10 @@ impl fmt::Display for AsciiChar {
#[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 {
Expand All @@ -595,24 +596,17 @@ impl fmt::Debug for AsciiChar {
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 {
const HEX_DIGITS: [AsciiChar; 16] = *b"0123456789abcdef".as_ascii().unwrap();
_ if self.to_u8().is_ascii_control() => {
const HEX_DIGITS: [AsciiChar; 16] = *b"0123456789abcdef".as_ascii().unwrap();

let hi = HEX_DIGITS[usize::from(byte >> 4)];
let lo = HEX_DIGITS[usize::from(byte & 0xf)];
([AsciiChar::ReverseSolidus, AsciiChar::SmallX, hi, lo], 4)
}
let byte = self.to_u8();
let hi = HEX_DIGITS[usize::from(byte >> 4)];
let lo = HEX_DIGITS[usize::from(byte & 0xf)];
([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 changes: 28 additions & 0 deletions library/core/tests/ascii_char.rs
Original file line number Diff line number Diff line change
@@ -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}");
}
}
1 change: 1 addition & 0 deletions library/core/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ mod alloc;
mod any;
mod array;
mod ascii;
mod ascii_char;
mod asserting;
mod async_iter;
mod atomic;
Expand Down
Loading