#
core/ascii/
ascii_char.rs

    1//! This uses the name `AsciiChar`, even though it's not exposed that way right now,
    2//! because it avoids a whole bunch of "are you sure you didn't mean `char`?"
    3//! suggestions from rustc if you get anything slightly wrong in here, and overall
    4//! helps with clarity as we're also referring to `char` intentionally in here.
    5
    6use crate::mem::transmute;
    7use crate::{assert_unsafe_precondition, fmt};
    8
    9/// One of the 128 Unicode characters from U+0000 through U+007F,
    10/// often known as the [ASCII] subset.
    11///
    12/// Officially, this is the first [block] in Unicode, _Basic Latin_.
    13/// For details, see the [*C0 Controls and Basic Latin*][chart] code chart.
    14///
    15/// This block was based on older 7-bit character code standards such as
    16/// ANSI X3.4-1977, ISO 646-1973, and [NIST FIPS 1-2].
    17///
    18/// # When to use this
    19///
    20/// The main advantage of this subset is that it's always valid UTF-8.  As such,
    21/// the `&[ascii::Char]` -> `&str` conversion function (as well as other related
    22/// ones) are O(1): *no* runtime checks are needed.
    23///
    24/// If you're consuming strings, you should usually handle Unicode and thus
    25/// accept `str`s, not limit yourself to `ascii::Char`s.
    26///
    27/// However, certain formats are intentionally designed to produce ASCII-only
    28/// output in order to be 8-bit-clean.  In those cases, it can be simpler and
    29/// faster to generate `ascii::Char`s instead of dealing with the variable width
    30/// properties of general UTF-8 encoded strings, while still allowing the result
    31/// to be used freely with other Rust things that deal in general `str`s.
    32///
    33/// For example, a UUID library might offer a way to produce the string
    34/// representation of a UUID as an `[ascii::Char; 36]` to avoid memory
    35/// allocation yet still allow it to be used as UTF-8 via `as_str` without
    36/// paying for validation (or needing `unsafe` code) the way it would if it
    37/// were provided as a `[u8; 36]`.
    38///
    39/// # Layout
    40///
    41/// This type is guaranteed to have a size and alignment of 1 byte.
    42///
    43/// # Names
    44///
    45/// The variants on this type are [Unicode names][NamesList] of the characters
    46/// in upper camel case, with a few tweaks:
    47/// - For `<control>` characters, the primary alias name is used.
    48/// - `LATIN` is dropped, as this block has no non-latin letters.
    49/// - `LETTER` is dropped, as `CAPITAL`/`SMALL` suffices in this block.
    50/// - `DIGIT`s use a single digit rather than writing out `ZERO`, `ONE`, etc.
    51///
    52/// [ASCII]: https://www.unicode.org/glossary/index.html#ASCII
    53/// [block]: https://www.unicode.org/glossary/index.html#block
    54/// [chart]: https://www.unicode.org/charts/PDF/U0000.pdf
    55/// [NIST FIPS 1-2]: https://nvlpubs.nist.gov/nistpubs/Legacy/FIPS/fipspub1-2-1977.pdf
    56/// [NamesList]: https://www.unicode.org/Public/15.0.0/ucd/NamesList.txt
    57#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
    58#[unstable(feature = "ascii_char", issue = "110998")]
    59#[repr(u8)]
    60pub enum AsciiChar {
    61    /// U+0000 (The default variant)
    62    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    63    Null = 0,
    64    /// U+0001
    65    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    66    StartOfHeading = 1,
    67    /// U+0002
    68    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    69    StartOfText = 2,
    70    /// U+0003
    71    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    72    EndOfText = 3,
    73    /// U+0004
    74    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    75    EndOfTransmission = 4,
    76    /// U+0005
    77    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    78    Enquiry = 5,
    79    /// U+0006
    80    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    81    Acknowledge = 6,
    82    /// U+0007
    83    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    84    Bell = 7,
    85    /// U+0008
    86    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    87    Backspace = 8,
    88    /// U+0009
    89    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    90    CharacterTabulation = 9,
    91    /// U+000A
    92    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    93    LineFeed = 10,
    94    /// U+000B
    95    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    96    LineTabulation = 11,
    97    /// U+000C
    98    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    99    FormFeed = 12,
    100    /// U+000D
    101    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    102    CarriageReturn = 13,
    103    /// U+000E
    104    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    105    ShiftOut = 14,
    106    /// U+000F
    107    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    108    ShiftIn = 15,
    109    /// U+0010
    110    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    111    DataLinkEscape = 16,
    112    /// U+0011
    113    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    114    DeviceControlOne = 17,
    115    /// U+0012
    116    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    117    DeviceControlTwo = 18,
    118    /// U+0013
    119    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    120    DeviceControlThree = 19,
    121    /// U+0014
    122    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    123    DeviceControlFour = 20,
    124    /// U+0015
    125    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    126    NegativeAcknowledge = 21,
    127    /// U+0016
    128    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    129    SynchronousIdle = 22,
    130    /// U+0017
    131    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    132    EndOfTransmissionBlock = 23,
    133    /// U+0018
    134    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    135    Cancel = 24,
    136    /// U+0019
    137    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    138    EndOfMedium = 25,
    139    /// U+001A
    140    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    141    Substitute = 26,
    142    /// U+001B
    143    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    144    Escape = 27,
    145    /// U+001C
    146    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    147    InformationSeparatorFour = 28,
    148    /// U+001D
    149    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    150    InformationSeparatorThree = 29,
    151    /// U+001E
    152    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    153    InformationSeparatorTwo = 30,
    154    /// U+001F
    155    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    156    InformationSeparatorOne = 31,
    157    /// U+0020
    158    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    159    Space = 32,
    160    /// U+0021
    161    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    162    ExclamationMark = 33,
    163    /// U+0022
    164    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    165    QuotationMark = 34,
    166    /// U+0023
    167    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    168    NumberSign = 35,
    169    /// U+0024
    170    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    171    DollarSign = 36,
    172    /// U+0025
    173    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    174    PercentSign = 37,
    175    /// U+0026
    176    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    177    Ampersand = 38,
    178    /// U+0027
    179    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    180    Apostrophe = 39,
    181    /// U+0028
    182    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    183    LeftParenthesis = 40,
    184    /// U+0029
    185    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    186    RightParenthesis = 41,
    187    /// U+002A
    188    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    189    Asterisk = 42,
    190    /// U+002B
    191    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    192    PlusSign = 43,
    193    /// U+002C
    194    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    195    Comma = 44,
    196    /// U+002D
    197    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    198    HyphenMinus = 45,
    199    /// U+002E
    200    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    201    FullStop = 46,
    202    /// U+002F
    203    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    204    Solidus = 47,
    205    /// U+0030
    206    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    207    Digit0 = 48,
    208    /// U+0031
    209    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    210    Digit1 = 49,
    211    /// U+0032
    212    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    213    Digit2 = 50,
    214    /// U+0033
    215    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    216    Digit3 = 51,
    217    /// U+0034
    218    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    219    Digit4 = 52,
    220    /// U+0035
    221    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    222    Digit5 = 53,
    223    /// U+0036
    224    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    225    Digit6 = 54,
    226    /// U+0037
    227    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    228    Digit7 = 55,
    229    /// U+0038
    230    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    231    Digit8 = 56,
    232    /// U+0039
    233    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    234    Digit9 = 57,
    235    /// U+003A
    236    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    237    Colon = 58,
    238    /// U+003B
    239    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    240    Semicolon = 59,
    241    /// U+003C
    242    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    243    LessThanSign = 60,
    244    /// U+003D
    245    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    246    EqualsSign = 61,
    247    /// U+003E
    248    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    249    GreaterThanSign = 62,
    250    /// U+003F
    251    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    252    QuestionMark = 63,
    253    /// U+0040
    254    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    255    CommercialAt = 64,
    256    /// U+0041
    257    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    258    CapitalA = 65,
    259    /// U+0042
    260    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    261    CapitalB = 66,
    262    /// U+0043
    263    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    264    CapitalC = 67,
    265    /// U+0044
    266    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    267    CapitalD = 68,
    268    /// U+0045
    269    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    270    CapitalE = 69,
    271    /// U+0046
    272    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    273    CapitalF = 70,
    274    /// U+0047
    275    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    276    CapitalG = 71,
    277    /// U+0048
    278    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    279    CapitalH = 72,
    280    /// U+0049
    281    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    282    CapitalI = 73,
    283    /// U+004A
    284    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    285    CapitalJ = 74,
    286    /// U+004B
    287    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    288    CapitalK = 75,
    289    /// U+004C
    290    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    291    CapitalL = 76,
    292    /// U+004D
    293    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    294    CapitalM = 77,
    295    /// U+004E
    296    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    297    CapitalN = 78,
    298    /// U+004F
    299    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    300    CapitalO = 79,
    301    /// U+0050
    302    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    303    CapitalP = 80,
    304    /// U+0051
    305    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    306    CapitalQ = 81,
    307    /// U+0052
    308    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    309    CapitalR = 82,
    310    /// U+0053
    311    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    312    CapitalS = 83,
    313    /// U+0054
    314    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    315    CapitalT = 84,
    316    /// U+0055
    317    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    318    CapitalU = 85,
    319    /// U+0056
    320    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    321    CapitalV = 86,
    322    /// U+0057
    323    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    324    CapitalW = 87,
    325    /// U+0058
    326    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    327    CapitalX = 88,
    328    /// U+0059
    329    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    330    CapitalY = 89,
    331    /// U+005A
    332    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    333    CapitalZ = 90,
    334    /// U+005B
    335    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    336    LeftSquareBracket = 91,
    337    /// U+005C
    338    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    339    ReverseSolidus = 92,
    340    /// U+005D
    341    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    342    RightSquareBracket = 93,
    343    /// U+005E
    344    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    345    CircumflexAccent = 94,
    346    /// U+005F
    347    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    348    LowLine = 95,
    349    /// U+0060
    350    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    351    GraveAccent = 96,
    352    /// U+0061
    353    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    354    SmallA = 97,
    355    /// U+0062
    356    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    357    SmallB = 98,
    358    /// U+0063
    359    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    360    SmallC = 99,
    361    /// U+0064
    362    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    363    SmallD = 100,
    364    /// U+0065
    365    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    366    SmallE = 101,
    367    /// U+0066
    368    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    369    SmallF = 102,
    370    /// U+0067
    371    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    372    SmallG = 103,
    373    /// U+0068
    374    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    375    SmallH = 104,
    376    /// U+0069
    377    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    378    SmallI = 105,
    379    /// U+006A
    380    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    381    SmallJ = 106,
    382    /// U+006B
    383    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    384    SmallK = 107,
    385    /// U+006C
    386    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    387    SmallL = 108,
    388    /// U+006D
    389    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    390    SmallM = 109,
    391    /// U+006E
    392    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    393    SmallN = 110,
    394    /// U+006F
    395    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    396    SmallO = 111,
    397    /// U+0070
    398    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    399    SmallP = 112,
    400    /// U+0071
    401    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    402    SmallQ = 113,
    403    /// U+0072
    404    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    405    SmallR = 114,
    406    /// U+0073
    407    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    408    SmallS = 115,
    409    /// U+0074
    410    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    411    SmallT = 116,
    412    /// U+0075
    413    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    414    SmallU = 117,
    415    /// U+0076
    416    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    417    SmallV = 118,
    418    /// U+0077
    419    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    420    SmallW = 119,
    421    /// U+0078
    422    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    423    SmallX = 120,
    424    /// U+0079
    425    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    426    SmallY = 121,
    427    /// U+007A
    428    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    429    SmallZ = 122,
    430    /// U+007B
    431    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    432    LeftCurlyBracket = 123,
    433    /// U+007C
    434    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    435    VerticalLine = 124,
    436    /// U+007D
    437    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    438    RightCurlyBracket = 125,
    439    /// U+007E
    440    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    441    Tilde = 126,
    442    /// U+007F
    443    #[unstable(feature = "ascii_char_variants", issue = "110998")]
    444    Delete = 127,
    445}
    446
    447impl AsciiChar {
    448    /// The character with the lowest ASCII code.
    449    #[unstable(feature = "ascii_char", issue = "110998")]
    450    pub const MIN: Self = Self::Null;
    451
    452    /// The character with the highest ASCII code.
    453    #[unstable(feature = "ascii_char", issue = "110998")]
    454    pub const MAX: Self = Self::Delete;
    455
    456    /// Creates an ASCII character from the byte `b`,
    457    /// or returns `None` if it's too large.
    458    #[unstable(feature = "ascii_char", issue = "110998")]
    459    #[inline]
    460    pub const fn from_u8(b: u8) -> Option<Self> {
    461        if b <= 127 {
    462            // SAFETY: Just checked that `b` is in-range
    463            Some(unsafe { Self::from_u8_unchecked(b) })
    464        } else {
    465            None
    466        }
    467    }
    468
    469    /// Creates an ASCII character from the byte `b`,
    470    /// without checking whether it's valid.
    471    ///
    472    /// # Safety
    473    ///
    474    /// `b` must be in `0..=127`, or else this is UB.
    475    #[unstable(feature = "ascii_char", issue = "110998")]
    476    #[inline]
    477    pub const unsafe fn from_u8_unchecked(b: u8) -> Self {
    478        // SAFETY: Our safety precondition is that `b` is in-range.
    479        unsafe { transmute(b) }
    480    }
    481
    482    /// When passed the *number* `0`, `1`, …, `9`, returns the *character*
    483    /// `'0'`, `'1'`, …, `'9'` respectively.
    484    ///
    485    /// If `d >= 10`, returns `None`.
    486    #[unstable(feature = "ascii_char", issue = "110998")]
    487    #[inline]
    488    pub const fn digit(d: u8) -> Option<Self> {
    489        if d < 10 {
    490            // SAFETY: Just checked it's in-range.
    491            Some(unsafe { Self::digit_unchecked(d) })
    492        } else {
    493            None
    494        }
    495    }
    496
    497    /// When passed the *number* `0`, `1`, …, `9`, returns the *character*
    498    /// `'0'`, `'1'`, …, `'9'` respectively, without checking that it's in-range.
    499    ///
    500    /// # Safety
    501    ///
    502    /// This is immediate UB if called with `d > 64`.
    503    ///
    504    /// If `d >= 10` and `d <= 64`, this is allowed to return any value or panic.
    505    /// Notably, it should not be expected to return hex digits, or any other
    506    /// reasonable extension of the decimal digits.
    507    ///
    508    /// (This loose safety condition is intended to simplify soundness proofs
    509    /// when writing code using this method, since the implementation doesn't
    510    /// need something really specific, not to make those other arguments do
    511    /// something useful. It might be tightened before stabilization.)
    512    #[unstable(feature = "ascii_char", issue = "110998")]
    513    #[inline]
    514    #[track_caller]
    515    pub const unsafe fn digit_unchecked(d: u8) -> Self {
    516        assert_unsafe_precondition!(
    517            check_language_ub,
    518            "`ascii::Char::digit_unchecked` input cannot exceed 9.",
    519            (d: u8 = d) => d < 10
    520        );
    521
    522        // SAFETY: `'0'` through `'9'` are U+00030 through U+0039,
    523        // so because `d` must be 64 or less the addition can return at most
    524        // 112 (0x70), which doesn't overflow and is within the ASCII range.
    525        unsafe {
    526            let byte = b'0'.unchecked_add(d);
    527            Self::from_u8_unchecked(byte)
    528        }
    529    }
    530
    531    /// Gets this ASCII character as a byte.
    532    #[unstable(feature = "ascii_char", issue = "110998")]
    533    #[inline]
    534    pub const fn to_u8(self) -> u8 {
    535        self as u8
    536    }
    537
    538    /// Gets this ASCII character as a `char` Unicode Scalar Value.
    539    #[unstable(feature = "ascii_char", issue = "110998")]
    540    #[inline]
    541    pub const fn to_char(self) -> char {
    542        self as u8 as char
    543    }
    544
    545    /// Views this ASCII character as a one-code-unit UTF-8 `str`.
    546    #[unstable(feature = "ascii_char", issue = "110998")]
    547    #[inline]
    548    pub const fn as_str(&self) -> &str {
    549        crate::slice::from_ref(self).as_str()
    550    }
    551
    552    /// Makes a copy of the value in its upper case equivalent.
    553    ///
    554    /// Letters 'a' to 'z' are mapped to 'A' to 'Z'.
    555    ///
    556    /// To uppercase the value in-place, use [`make_uppercase`].
    557    ///
    558    /// # Examples
    559    ///
    560    /// ```
    561    /// #![feature(ascii_char, ascii_char_variants)]
    562    /// use std::ascii;
    563    ///
    564    /// let lowercase_a = ascii::Char::SmallA;
    565    ///
    566    /// assert_eq!(
    567    ///     ascii::Char::CapitalA,
    568    ///     lowercase_a.to_uppercase(),
    569    /// );
    570    /// ```
    571    ///
    572    /// [`make_uppercase`]: Self::make_uppercase
    573    #[must_use = "to uppercase the value in-place, use `make_uppercase()`"]
    574    #[unstable(feature = "ascii_char", issue = "110998")]
    575    #[inline]
    576    pub const fn to_uppercase(self) -> Self {
    577        let uppercase_byte = self.to_u8().to_ascii_uppercase();
    578        // SAFETY: Toggling the 6th bit won't convert ASCII to non-ASCII.
    579        unsafe { Self::from_u8_unchecked(uppercase_byte) }
    580    }
    581
    582    /// Makes a copy of the value in its lower case equivalent.
    583    ///
    584    /// Letters 'A' to 'Z' are mapped to 'a' to 'z'.
    585    ///
    586    /// To lowercase the value in-place, use [`make_lowercase`].
    587    ///
    588    /// # Examples
    589    ///
    590    /// ```
    591    /// #![feature(ascii_char, ascii_char_variants)]
    592    /// use std::ascii;
    593    ///
    594    /// let uppercase_a = ascii::Char::CapitalA;
    595    ///
    596    /// assert_eq!(
    597    ///     ascii::Char::SmallA,
    598    ///     uppercase_a.to_lowercase(),
    599    /// );
    600    /// ```
    601    ///
    602    /// [`make_lowercase`]: Self::make_lowercase
    603    #[must_use = "to lowercase the value in-place, use `make_lowercase()`"]
    604    #[unstable(feature = "ascii_char", issue = "110998")]
    605    #[inline]
    606    pub const fn to_lowercase(self) -> Self {
    607        let lowercase_byte = self.to_u8().to_ascii_lowercase();
    608        // SAFETY: Setting the 6th bit won't convert ASCII to non-ASCII.
    609        unsafe { Self::from_u8_unchecked(lowercase_byte) }
    610    }
    611
    612    /// Checks that two values are a case-insensitive match.
    613    ///
    614    /// This is equivalent to `to_lowercase(a) == to_lowercase(b)`.
    615    ///
    616    /// # Examples
    617    ///
    618    /// ```
    619    /// #![feature(ascii_char, ascii_char_variants)]
    620    /// use std::ascii;
    621    ///
    622    /// let lowercase_a = ascii::Char::SmallA;
    623    /// let uppercase_a = ascii::Char::CapitalA;
    624    ///
    625    /// assert!(lowercase_a.eq_ignore_case(uppercase_a));
    626    /// ```
    627    #[unstable(feature = "ascii_char", issue = "110998")]
    628    #[inline]
    629    pub const fn eq_ignore_case(self, other: Self) -> bool {
    630        // FIXME(const-hack) `arg.to_u8().to_ascii_lowercase()` -> `arg.to_lowercase()`
    631        // once `PartialEq` is const for `Self`.
    632        self.to_u8().to_ascii_lowercase() == other.to_u8().to_ascii_lowercase()
    633    }
    634
    635    /// Converts this value to its upper case equivalent in-place.
    636    ///
    637    /// Letters 'a' to 'z' are mapped to 'A' to 'Z'.
    638    ///
    639    /// To return a new uppercased value without modifying the existing one, use
    640    /// [`to_uppercase`].
    641    ///
    642    /// # Examples
    643    ///
    644    /// ```
    645    /// #![feature(ascii_char, ascii_char_variants)]
    646    /// use std::ascii;
    647    ///
    648    /// let mut letter_a = ascii::Char::SmallA;
    649    ///
    650    /// letter_a.make_uppercase();
    651    ///
    652    /// assert_eq!(ascii::Char::CapitalA, letter_a);
    653    /// ```
    654    ///
    655    /// [`to_uppercase`]: Self::to_uppercase
    656    #[unstable(feature = "ascii_char", issue = "110998")]
    657    #[inline]
    658    pub const fn make_uppercase(&mut self) {
    659        *self = self.to_uppercase();
    660    }
    661
    662    /// Converts this value to its lower case equivalent in-place.
    663    ///
    664    /// Letters 'A' to 'Z' are mapped to 'a' to 'z'.
    665    ///
    666    /// To return a new lowercased value without modifying the existing one, use
    667    /// [`to_lowercase`].
    668    ///
    669    /// # Examples
    670    ///
    671    /// ```
    672    /// #![feature(ascii_char, ascii_char_variants)]
    673    /// use std::ascii;
    674    ///
    675    /// let mut letter_a = ascii::Char::CapitalA;
    676    ///
    677    /// letter_a.make_lowercase();
    678    ///
    679    /// assert_eq!(ascii::Char::SmallA, letter_a);
    680    /// ```
    681    ///
    682    /// [`to_lowercase`]: Self::to_lowercase
    683    #[unstable(feature = "ascii_char", issue = "110998")]
    684    #[inline]
    685    pub const fn make_lowercase(&mut self) {
    686        *self = self.to_lowercase();
    687    }
    688
    689    /// Checks if the value is an alphabetic character:
    690    ///
    691    /// - 0x41 'A' ..= 0x5A 'Z', or
    692    /// - 0x61 'a' ..= 0x7A 'z'.
    693    ///
    694    /// # Examples
    695    ///
    696    /// ```
    697    /// #![feature(ascii_char, ascii_char_variants)]
    698    /// use std::ascii;
    699    ///
    700    /// let uppercase_a = ascii::Char::CapitalA;
    701    /// let uppercase_g = ascii::Char::CapitalG;
    702    /// let a = ascii::Char::SmallA;
    703    /// let g = ascii::Char::SmallG;
    704    /// let zero = ascii::Char::Digit0;
    705    /// let percent = ascii::Char::PercentSign;
    706    /// let space = ascii::Char::Space;
    707    /// let lf = ascii::Char::LineFeed;
    708    /// let esc = ascii::Char::Escape;
    709    ///
    710    /// assert!(uppercase_a.is_alphabetic());
    711    /// assert!(uppercase_g.is_alphabetic());
    712    /// assert!(a.is_alphabetic());
    713    /// assert!(g.is_alphabetic());
    714    /// assert!(!zero.is_alphabetic());
    715    /// assert!(!percent.is_alphabetic());
    716    /// assert!(!space.is_alphabetic());
    717    /// assert!(!lf.is_alphabetic());
    718    /// assert!(!esc.is_alphabetic());
    719    /// ```
    720    #[must_use]
    721    #[unstable(feature = "ascii_char", issue = "110998")]
    722    #[inline]
    723    pub const fn is_alphabetic(self) -> bool {
    724        self.to_u8().is_ascii_alphabetic()
    725    }
    726
    727    /// Checks if the value is an uppercase character:
    728    /// 0x41 'A' ..= 0x5A 'Z'.
    729    ///
    730    /// # Examples
    731    ///
    732    /// ```
    733    /// #![feature(ascii_char, ascii_char_variants)]
    734    /// use std::ascii;
    735    ///
    736    /// let uppercase_a = ascii::Char::CapitalA;
    737    /// let uppercase_g = ascii::Char::CapitalG;
    738    /// let a = ascii::Char::SmallA;
    739    /// let g = ascii::Char::SmallG;
    740    /// let zero = ascii::Char::Digit0;
    741    /// let percent = ascii::Char::PercentSign;
    742    /// let space = ascii::Char::Space;
    743    /// let lf = ascii::Char::LineFeed;
    744    /// let esc = ascii::Char::Escape;
    745    ///
    746    /// assert!(uppercase_a.is_uppercase());
    747    /// assert!(uppercase_g.is_uppercase());
    748    /// assert!(!a.is_uppercase());
    749    /// assert!(!g.is_uppercase());
    750    /// assert!(!zero.is_uppercase());
    751    /// assert!(!percent.is_uppercase());
    752    /// assert!(!space.is_uppercase());
    753    /// assert!(!lf.is_uppercase());
    754    /// assert!(!esc.is_uppercase());
    755    /// ```
    756    #[must_use]
    757    #[unstable(feature = "ascii_char", issue = "110998")]
    758    #[inline]
    759    pub const fn is_uppercase(self) -> bool {
    760        self.to_u8().is_ascii_uppercase()
    761    }
    762
    763    /// Checks if the value is a lowercase character:
    764    /// 0x61 'a' ..= 0x7A 'z'.
    765    ///
    766    /// # Examples
    767    ///
    768    /// ```
    769    /// #![feature(ascii_char, ascii_char_variants)]
    770    /// use std::ascii;
    771    ///
    772    /// let uppercase_a = ascii::Char::CapitalA;
    773    /// let uppercase_g = ascii::Char::CapitalG;
    774    /// let a = ascii::Char::SmallA;
    775    /// let g = ascii::Char::SmallG;
    776    /// let zero = ascii::Char::Digit0;
    777    /// let percent = ascii::Char::PercentSign;
    778    /// let space = ascii::Char::Space;
    779    /// let lf = ascii::Char::LineFeed;
    780    /// let esc = ascii::Char::Escape;
    781    ///
    782    /// assert!(!uppercase_a.is_lowercase());
    783    /// assert!(!uppercase_g.is_lowercase());
    784    /// assert!(a.is_lowercase());
    785    /// assert!(g.is_lowercase());
    786    /// assert!(!zero.is_lowercase());
    787    /// assert!(!percent.is_lowercase());
    788    /// assert!(!space.is_lowercase());
    789    /// assert!(!lf.is_lowercase());
    790    /// assert!(!esc.is_lowercase());
    791    /// ```
    792    #[must_use]
    793    #[unstable(feature = "ascii_char", issue = "110998")]
    794    #[inline]
    795    pub const fn is_lowercase(self) -> bool {
    796        self.to_u8().is_ascii_lowercase()
    797    }
    798
    799    /// Checks if the value is an alphanumeric character:
    800    ///
    801    /// - 0x41 'A' ..= 0x5A 'Z', or
    802    /// - 0x61 'a' ..= 0x7A 'z', or
    803    /// - 0x30 '0' ..= 0x39 '9'.
    804    ///
    805    /// # Examples
    806    ///
    807    /// ```
    808    /// #![feature(ascii_char, ascii_char_variants)]
    809    /// use std::ascii;
    810    ///
    811    /// let uppercase_a = ascii::Char::CapitalA;
    812    /// let uppercase_g = ascii::Char::CapitalG;
    813    /// let a = ascii::Char::SmallA;
    814    /// let g = ascii::Char::SmallG;
    815    /// let zero = ascii::Char::Digit0;
    816    /// let percent = ascii::Char::PercentSign;
    817    /// let space = ascii::Char::Space;
    818    /// let lf = ascii::Char::LineFeed;
    819    /// let esc = ascii::Char::Escape;
    820    ///
    821    /// assert!(uppercase_a.is_alphanumeric());
    822    /// assert!(uppercase_g.is_alphanumeric());
    823    /// assert!(a.is_alphanumeric());
    824    /// assert!(g.is_alphanumeric());
    825    /// assert!(zero.is_alphanumeric());
    826    /// assert!(!percent.is_alphanumeric());
    827    /// assert!(!space.is_alphanumeric());
    828    /// assert!(!lf.is_alphanumeric());
    829    /// assert!(!esc.is_alphanumeric());
    830    /// ```
    831    #[must_use]
    832    #[unstable(feature = "ascii_char", issue = "110998")]
    833    #[inline]
    834    pub const fn is_alphanumeric(self) -> bool {
    835        self.to_u8().is_ascii_alphanumeric()
    836    }
    837
    838    /// Checks if the value is a decimal digit:
    839    /// 0x30 '0' ..= 0x39 '9'.
    840    ///
    841    /// # Examples
    842    ///
    843    /// ```
    844    /// #![feature(ascii_char, ascii_char_variants)]
    845    /// use std::ascii;
    846    ///
    847    /// let uppercase_a = ascii::Char::CapitalA;
    848    /// let uppercase_g = ascii::Char::CapitalG;
    849    /// let a = ascii::Char::SmallA;
    850    /// let g = ascii::Char::SmallG;
    851    /// let zero = ascii::Char::Digit0;
    852    /// let percent = ascii::Char::PercentSign;
    853    /// let space = ascii::Char::Space;
    854    /// let lf = ascii::Char::LineFeed;
    855    /// let esc = ascii::Char::Escape;
    856    ///
    857    /// assert!(!uppercase_a.is_digit());
    858    /// assert!(!uppercase_g.is_digit());
    859    /// assert!(!a.is_digit());
    860    /// assert!(!g.is_digit());
    861    /// assert!(zero.is_digit());
    862    /// assert!(!percent.is_digit());
    863    /// assert!(!space.is_digit());
    864    /// assert!(!lf.is_digit());
    865    /// assert!(!esc.is_digit());
    866    /// ```
    867    #[must_use]
    868    #[unstable(feature = "ascii_char", issue = "110998")]
    869    #[inline]
    870    pub const fn is_digit(self) -> bool {
    871        self.to_u8().is_ascii_digit()
    872    }
    873
    874    /// Checks if the value is an octal digit:
    875    /// 0x30 '0' ..= 0x37 '7'.
    876    ///
    877    /// # Examples
    878    ///
    879    /// ```
    880    /// #![feature(ascii_char, ascii_char_variants, is_ascii_octdigit)]
    881    ///
    882    /// use std::ascii;
    883    ///
    884    /// let uppercase_a = ascii::Char::CapitalA;
    885    /// let a = ascii::Char::SmallA;
    886    /// let zero = ascii::Char::Digit0;
    887    /// let seven = ascii::Char::Digit7;
    888    /// let eight = ascii::Char::Digit8;
    889    /// let percent = ascii::Char::PercentSign;
    890    /// let lf = ascii::Char::LineFeed;
    891    /// let esc = ascii::Char::Escape;
    892    ///
    893    /// assert!(!uppercase_a.is_octdigit());
    894    /// assert!(!a.is_octdigit());
    895    /// assert!(zero.is_octdigit());
    896    /// assert!(seven.is_octdigit());
    897    /// assert!(!eight.is_octdigit());
    898    /// assert!(!percent.is_octdigit());
    899    /// assert!(!lf.is_octdigit());
    900    /// assert!(!esc.is_octdigit());
    901    /// ```
    902    #[must_use]
    903    // This is blocked on two unstable features. Please ensure both are
    904    // stabilized before marking this method as stable.
    905    #[unstable(feature = "ascii_char", issue = "110998")]
    906    // #[unstable(feature = "is_ascii_octdigit", issue = "101288")]
    907    #[inline]
    908    pub const fn is_octdigit(self) -> bool {
    909        self.to_u8().is_ascii_octdigit()
    910    }
    911
    912    /// Checks if the value is a hexadecimal digit:
    913    ///
    914    /// - 0x30 '0' ..= 0x39 '9', or
    915    /// - 0x41 'A' ..= 0x46 'F', or
    916    /// - 0x61 'a' ..= 0x66 'f'.
    917    ///
    918    /// # Examples
    919    ///
    920    /// ```
    921    /// #![feature(ascii_char, ascii_char_variants)]
    922    /// use std::ascii;
    923    ///
    924    /// let uppercase_a = ascii::Char::CapitalA;
    925    /// let uppercase_g = ascii::Char::CapitalG;
    926    /// let a = ascii::Char::SmallA;
    927    /// let g = ascii::Char::SmallG;
    928    /// let zero = ascii::Char::Digit0;
    929    /// let percent = ascii::Char::PercentSign;
    930    /// let space = ascii::Char::Space;
    931    /// let lf = ascii::Char::LineFeed;
    932    /// let esc = ascii::Char::Escape;
    933    ///
    934    /// assert!(uppercase_a.is_hexdigit());
    935    /// assert!(!uppercase_g.is_hexdigit());
    936    /// assert!(a.is_hexdigit());
    937    /// assert!(!g.is_hexdigit());
    938    /// assert!(zero.is_hexdigit());
    939    /// assert!(!percent.is_hexdigit());
    940    /// assert!(!space.is_hexdigit());
    941    /// assert!(!lf.is_hexdigit());
    942    /// assert!(!esc.is_hexdigit());
    943    /// ```
    944    #[must_use]
    945    #[unstable(feature = "ascii_char", issue = "110998")]
    946    #[inline]
    947    pub const fn is_hexdigit(self) -> bool {
    948        self.to_u8().is_ascii_hexdigit()
    949    }
    950
    951    /// Checks if the value is a punctuation character:
    952    ///
    953    /// - 0x21 ..= 0x2F `! " # $ % & ' ( ) * + , - . /`, or
    954    /// - 0x3A ..= 0x40 `: ; < = > ? @`, or
    955    /// - 0x5B ..= 0x60 `` [ \ ] ^ _ ` ``, or
    956    /// - 0x7B ..= 0x7E `{ | } ~`
    957    ///
    958    /// # Examples
    959    ///
    960    /// ```
    961    /// #![feature(ascii_char, ascii_char_variants)]
    962    /// use std::ascii;
    963    ///
    964    /// let uppercase_a = ascii::Char::CapitalA;
    965    /// let uppercase_g = ascii::Char::CapitalG;
    966    /// let a = ascii::Char::SmallA;
    967    /// let g = ascii::Char::SmallG;
    968    /// let zero = ascii::Char::Digit0;
    969    /// let percent = ascii::Char::PercentSign;
    970    /// let space = ascii::Char::Space;
    971    /// let lf = ascii::Char::LineFeed;
    972    /// let esc = ascii::Char::Escape;
    973    ///
    974    /// assert!(!uppercase_a.is_punctuation());
    975    /// assert!(!uppercase_g.is_punctuation());
    976    /// assert!(!a.is_punctuation());
    977    /// assert!(!g.is_punctuation());
    978    /// assert!(!zero.is_punctuation());
    979    /// assert!(percent.is_punctuation());
    980    /// assert!(!space.is_punctuation());
    981    /// assert!(!lf.is_punctuation());
    982    /// assert!(!esc.is_punctuation());
    983    /// ```
    984    #[must_use]
    985    #[unstable(feature = "ascii_char", issue = "110998")]
    986    #[inline]
    987    pub const fn is_punctuation(self) -> bool {
    988        self.to_u8().is_ascii_punctuation()
    989    }
    990
    991    /// Checks if the value is a graphic character:
    992    /// 0x21 '!' ..= 0x7E '~'.
    993    ///
    994    /// # Examples
    995    ///
    996    /// ```
    997    /// #![feature(ascii_char, ascii_char_variants)]
    998    /// use std::ascii;
    999    ///
    1000    /// let uppercase_a = ascii::Char::CapitalA;
    1001    /// let uppercase_g = ascii::Char::CapitalG;
    1002    /// let a = ascii::Char::SmallA;
    1003    /// let g = ascii::Char::SmallG;
    1004    /// let zero = ascii::Char::Digit0;
    1005    /// let percent = ascii::Char::PercentSign;
    1006    /// let space = ascii::Char::Space;
    1007    /// let lf = ascii::Char::LineFeed;
    1008    /// let esc = ascii::Char::Escape;
    1009    ///
    1010    /// assert!(uppercase_a.is_graphic());
    1011    /// assert!(uppercase_g.is_graphic());
    1012    /// assert!(a.is_graphic());
    1013    /// assert!(g.is_graphic());
    1014    /// assert!(zero.is_graphic());
    1015    /// assert!(percent.is_graphic());
    1016    /// assert!(!space.is_graphic());
    1017    /// assert!(!lf.is_graphic());
    1018    /// assert!(!esc.is_graphic());
    1019    /// ```
    1020    #[must_use]
    1021    #[unstable(feature = "ascii_char", issue = "110998")]
    1022    #[inline]
    1023    pub const fn is_graphic(self) -> bool {
    1024        self.to_u8().is_ascii_graphic()
    1025    }
    1026
    1027    /// Checks if the value is a whitespace character:
    1028    /// 0x20 SPACE, 0x09 HORIZONTAL TAB, 0x0A LINE FEED,
    1029    /// 0x0C FORM FEED, or 0x0D CARRIAGE RETURN.
    1030    ///
    1031    /// Rust uses the WhatWG Infra Standard's [definition of ASCII
    1032    /// whitespace][infra-aw]. There are several other definitions in
    1033    /// wide use. For instance, [the POSIX locale][pct] includes
    1034    /// 0x0B VERTICAL TAB as well as all the above characters,
    1035    /// but—from the very same specification—[the default rule for
    1036    /// "field splitting" in the Bourne shell][bfs] considers *only*
    1037    /// SPACE, HORIZONTAL TAB, and LINE FEED as whitespace.
    1038    ///
    1039    /// If you are writing a program that will process an existing
    1040    /// file format, check what that format's definition of whitespace is
    1041    /// before using this function.
    1042    ///
    1043    /// [infra-aw]: https://infra.spec.whatwg.org/#ascii-whitespace
    1044    /// [pct]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01
    1045    /// [bfs]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05
    1046    ///
    1047    /// # Examples
    1048    ///
    1049    /// ```
    1050    /// #![feature(ascii_char, ascii_char_variants)]
    1051    /// use std::ascii;
    1052    ///
    1053    /// let uppercase_a = ascii::Char::CapitalA;
    1054    /// let uppercase_g = ascii::Char::CapitalG;
    1055    /// let a = ascii::Char::SmallA;
    1056    /// let g = ascii::Char::SmallG;
    1057    /// let zero = ascii::Char::Digit0;
    1058    /// let percent = ascii::Char::PercentSign;
    1059    /// let space = ascii::Char::Space;
    1060    /// let lf = ascii::Char::LineFeed;
    1061    /// let esc = ascii::Char::Escape;
    1062    ///
    1063    /// assert!(!uppercase_a.is_whitespace());
    1064    /// assert!(!uppercase_g.is_whitespace());
    1065    /// assert!(!a.is_whitespace());
    1066    /// assert!(!g.is_whitespace());
    1067    /// assert!(!zero.is_whitespace());
    1068    /// assert!(!percent.is_whitespace());
    1069    /// assert!(space.is_whitespace());
    1070    /// assert!(lf.is_whitespace());
    1071    /// assert!(!esc.is_whitespace());
    1072    /// ```
    1073    #[must_use]
    1074    #[unstable(feature = "ascii_char", issue = "110998")]
    1075    #[inline]
    1076    pub const fn is_whitespace(self) -> bool {
    1077        self.to_u8().is_ascii_whitespace()
    1078    }
    1079
    1080    /// Checks if the value is a control character:
    1081    /// 0x00 NUL ..= 0x1F UNIT SEPARATOR, or 0x7F DELETE.
    1082    /// Note that most whitespace characters are control
    1083    /// characters, but SPACE is not.
    1084    ///
    1085    /// # Examples
    1086    ///
    1087    /// ```
    1088    /// #![feature(ascii_char, ascii_char_variants)]
    1089    /// use std::ascii;
    1090    ///
    1091    /// let uppercase_a = ascii::Char::CapitalA;
    1092    /// let uppercase_g = ascii::Char::CapitalG;
    1093    /// let a = ascii::Char::SmallA;
    1094    /// let g = ascii::Char::SmallG;
    1095    /// let zero = ascii::Char::Digit0;
    1096    /// let percent = ascii::Char::PercentSign;
    1097    /// let space = ascii::Char::Space;
    1098    /// let lf = ascii::Char::LineFeed;
    1099    /// let esc = ascii::Char::Escape;
    1100    ///
    1101    /// assert!(!uppercase_a.is_control());
    1102    /// assert!(!uppercase_g.is_control());
    1103    /// assert!(!a.is_control());
    1104    /// assert!(!g.is_control());
    1105    /// assert!(!zero.is_control());
    1106    /// assert!(!percent.is_control());
    1107    /// assert!(!space.is_control());
    1108    /// assert!(lf.is_control());
    1109    /// assert!(esc.is_control());
    1110    /// ```
    1111    #[must_use]
    1112    #[unstable(feature = "ascii_char", issue = "110998")]
    1113    #[inline]
    1114    pub const fn is_control(self) -> bool {
    1115        self.to_u8().is_ascii_control()
    1116    }
    1117
    1118    /// Returns an iterator that produces an escaped version of a
    1119    /// character.
    1120    ///
    1121    /// The behavior is identical to
    1122    /// [`ascii::escape_default`](crate::ascii::escape_default).
    1123    ///
    1124    /// # Examples
    1125    ///
    1126    /// ```
    1127    /// #![feature(ascii_char, ascii_char_variants)]
    1128    /// use std::ascii;
    1129    ///
    1130    /// let zero = ascii::Char::Digit0;
    1131    /// let tab = ascii::Char::CharacterTabulation;
    1132    /// let cr = ascii::Char::CarriageReturn;
    1133    /// let lf = ascii::Char::LineFeed;
    1134    /// let apostrophe = ascii::Char::Apostrophe;
    1135    /// let double_quote = ascii::Char::QuotationMark;
    1136    /// let backslash = ascii::Char::ReverseSolidus;
    1137    ///
    1138    /// assert_eq!("0", zero.escape_ascii().to_string());
    1139    /// assert_eq!("\\t", tab.escape_ascii().to_string());
    1140    /// assert_eq!("\\r", cr.escape_ascii().to_string());
    1141    /// assert_eq!("\\n", lf.escape_ascii().to_string());
    1142    /// assert_eq!("\\'", apostrophe.escape_ascii().to_string());
    1143    /// assert_eq!("\\\"", double_quote.escape_ascii().to_string());
    1144    /// assert_eq!("\\\\", backslash.escape_ascii().to_string());
    1145    /// ```
    1146    #[must_use = "this returns the escaped character as an iterator, \
    1147                  without modifying the original"]
    1148    #[unstable(feature = "ascii_char", issue = "110998")]
    1149    #[inline]
    1150    pub fn escape_ascii(self) -> super::EscapeDefault {
    1151        super::escape_default(self.to_u8())
    1152    }
    1153}
    1154
    1155macro_rules! into_int_impl {
    1156    ($($ty:ty)*) => {
    1157        $(
    1158            #[unstable(feature = "ascii_char", issue = "110998")]
    1159            #[rustc_const_unstable(feature = "const_try", issue = "74935")]
    1160            impl const From<AsciiChar> for $ty {
    1161                #[inline]
    1162                fn from(chr: AsciiChar) -> $ty {
    1163                    chr as u8 as $ty
    1164                }
    1165            }
    1166        )*
    1167    }
    1168}
    1169
    1170into_int_impl!(u8 u16 u32 u64 u128 char);
    1171
    1172impl [AsciiChar] {
    1173    /// Views this slice of ASCII characters as a UTF-8 `str`.
    1174    #[unstable(feature = "ascii_char", issue = "110998")]
    1175    #[inline]
    1176    pub const fn as_str(&self) -> &str {
    1177        let ascii_ptr: *const Self = self;
    1178        let str_ptr = ascii_ptr as *const str;
    1179        // SAFETY: Each ASCII codepoint in UTF-8 is encoded as one single-byte
    1180        // code unit having the same value as the ASCII byte.
    1181        unsafe { &*str_ptr }
    1182    }
    1183
    1184    /// Views this slice of ASCII characters as a slice of `u8` bytes.
    1185    #[unstable(feature = "ascii_char", issue = "110998")]
    1186    #[inline]
    1187    pub const fn as_bytes(&self) -> &[u8] {
    1188        self.as_str().as_bytes()
    1189    }
    1190}
    1191
    1192#[unstable(feature = "ascii_char", issue = "110998")]
    1193impl fmt::Display for AsciiChar {
    1194    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    1195        <str as fmt::Display>::fmt(self.as_str(), f)
    1196    }
    1197}
    1198
    1199#[unstable(feature = "ascii_char", issue = "110998")]
    1200impl fmt::Debug for AsciiChar {
    1201    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    1202        use AsciiChar::{Apostrophe, Null, ReverseSolidus as Backslash};
    1203
    1204        fn backslash(a: AsciiChar) -> ([AsciiChar; 6], usize) {
    1205            ([Apostrophe, Backslash, a, Apostrophe, Null, Null], 4)
    1206        }
    1207
    1208        let (buf, len) = match self {
    1209            AsciiChar::Null => backslash(AsciiChar::Digit0),
    1210            AsciiChar::CharacterTabulation => backslash(AsciiChar::SmallT),
    1211            AsciiChar::CarriageReturn => backslash(AsciiChar::SmallR),
    1212            AsciiChar::LineFeed => backslash(AsciiChar::SmallN),
    1213            AsciiChar::ReverseSolidus => backslash(AsciiChar::ReverseSolidus),
    1214            AsciiChar::Apostrophe => backslash(AsciiChar::Apostrophe),
    1215            _ if self.to_u8().is_ascii_control() => {
    1216                const HEX_DIGITS: [AsciiChar; 16] = *b"0123456789abcdef".as_ascii().unwrap();
    1217
    1218                let byte = self.to_u8();
    1219                let hi = HEX_DIGITS[usize::from(byte >> 4)];
    1220                let lo = HEX_DIGITS[usize::from(byte & 0xf)];
    1221                ([Apostrophe, Backslash, AsciiChar::SmallX, hi, lo, Apostrophe], 6)
    1222            }
    1223            _ => ([Apostrophe, *self, Apostrophe, Null, Null, Null], 3),
    1224        };
    1225
    1226        f.write_str(buf[..len].as_str())
    1227    }
    1228}