33//! suggestions from rustc if you get anything slightly wrong in here, and overall
44//! helps with clarity as we're also referring to `char` intentionally in here.
55
6- use crate :: fmt:: { self , Write } ;
6+ use crate :: fmt;
77use crate :: mem:: transmute;
88
99/// One of the 128 Unicode characters from U+0000 through U+007F,
@@ -474,7 +474,8 @@ impl AsciiChar {
474474 /// When passed the *number* `0`, `1`, …, `9`, returns the *character*
475475 /// `'0'`, `'1'`, …, `'9'` respectively.
476476 ///
477- /// If `d >= 10`, returns `None`.
477+ /// If `d >= 10`, returns `None`. To get a digit up to `d == 35`, use
478+ /// [`from_digit`](Self::from_digit) instead.
478479 #[ unstable( feature = "ascii_char" , issue = "110998" ) ]
479480 #[ inline]
480481 pub const fn digit ( d : u8 ) -> Option < Self > {
@@ -515,6 +516,37 @@ impl AsciiChar {
515516 }
516517 }
517518
519+ /// Returns a *character* digit corresponding to given numeric value of
520+ /// a digit.
521+ ///
522+ /// When passed the *number* `0`, `1`, …, `8`, `9`, `10`, …, `34`, `35`,
523+ /// returns the *character* `'0'`, `'1'`, …, `'8'`, `'9'`, `'a'`, …, `'y'`,
524+ /// `'z'` respectively.
525+ ///
526+ /// If `d >= 36`, returns `None`. To get a digit only for `d < 10`, use
527+ /// [`digit`](Self::digit) instead.
528+ ///
529+ /// # Example
530+ ///
531+ /// ```
532+ /// #![feature(ascii_char, ascii_char_variants)]
533+ /// use core::ascii::Char;
534+ ///
535+ /// assert_eq!(Some(Char::Digit0), Char::from_digit(0));
536+ /// assert_eq!(Some(Char::Digit9), Char::from_digit(9));
537+ /// assert_eq!(Some(Char::SmallA), Char::from_digit(10));
538+ /// assert_eq!(Some(Char::SmallF), Char::from_digit(15));
539+ /// assert_eq!(Some(Char::SmallZ), Char::from_digit(35));
540+ /// assert_eq!(None, Char::from_digit(36));
541+ /// ```
542+ #[ unstable( feature = "ascii_char" , issue = "110998" ) ]
543+ #[ inline]
544+ pub const fn from_digit ( d : u32 ) -> Option < Self > {
545+ const DIGITS : [ AsciiChar ; 36 ] =
546+ * b"0123456789abcdefghijklmnopqrstuvwxyz" . as_ascii ( ) . unwrap ( ) ;
547+ if d < 36 { Some ( DIGITS [ d as usize ] ) } else { None }
548+ }
549+
518550 /// Gets this ASCII character as a byte.
519551 #[ unstable( feature = "ascii_char" , issue = "110998" ) ]
520552 #[ inline]
@@ -567,12 +599,14 @@ impl fmt::Display for AsciiChar {
567599#[ unstable( feature = "ascii_char" , issue = "110998" ) ]
568600impl fmt:: Debug for AsciiChar {
569601 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
602+ use AsciiChar :: * ;
603+
570604 #[ inline]
571- fn backslash ( a : AsciiChar ) -> ( [ AsciiChar ; 4 ] , u8 ) {
572- ( [ AsciiChar :: ReverseSolidus , a , AsciiChar :: Null , AsciiChar :: Null ] , 2 )
605+ fn backslash ( ch : AsciiChar ) -> ( [ AsciiChar ; 6 ] , usize ) {
606+ ( [ Apostrophe , ReverseSolidus , ch , Apostrophe , Null , Null ] , 4 )
573607 }
574608
575- let ( buf, len) = match self {
609+ let ( buf, len) = match * self {
576610 AsciiChar :: Null => backslash ( AsciiChar :: Digit0 ) ,
577611 AsciiChar :: CharacterTabulation => backslash ( AsciiChar :: SmallT ) ,
578612 AsciiChar :: CarriageReturn => backslash ( AsciiChar :: SmallR ) ,
@@ -582,21 +616,15 @@ impl fmt::Debug for AsciiChar {
582616 _ => {
583617 let byte = self . to_u8 ( ) ;
584618 if !byte. is_ascii_control ( ) {
585- ( [ * self , AsciiChar :: Null , AsciiChar :: Null , AsciiChar :: Null ] , 1 )
619+ ( [ Apostrophe , * self , Apostrophe , Null , Null , Null ] , 3 )
586620 } else {
587- const HEX_DIGITS : [ AsciiChar ; 16 ] = * b"0123456789abcdef" . as_ascii ( ) . unwrap ( ) ;
588-
589- let hi = HEX_DIGITS [ usize:: from ( byte >> 4 ) ] ;
590- let lo = HEX_DIGITS [ usize:: from ( byte & 0xf ) ] ;
591- ( [ AsciiChar :: ReverseSolidus , AsciiChar :: SmallX , hi, lo] , 4 )
621+ let hi = Self :: from_digit ( u32:: from ( byte >> 4 ) ) . unwrap ( ) ;
622+ let lo = Self :: from_digit ( u32:: from ( byte & 0xf ) ) . unwrap ( ) ;
623+ ( [ Apostrophe , ReverseSolidus , SmallX , hi, lo, Apostrophe ] , 6 )
592624 }
593625 }
594626 } ;
595627
596- f. write_char ( '\'' ) ?;
597- for byte in & buf[ ..len as usize ] {
598- f. write_str ( byte. as_str ( ) ) ?;
599- }
600- f. write_char ( '\'' )
628+ f. write_str ( buf[ ..len] . as_str ( ) )
601629 }
602630}
0 commit comments