ascii.rs - source
Description: Source of the Rust file `library/core/src/ascii.rs`.

#
core/
ascii.rs

    1//! Operations on ASCII strings and characters.
    2//!
    3//! Most string operations in Rust act on UTF-8 strings. However, at times it
    4//! makes more sense to only consider the ASCII character set for a specific
    5//! operation.
    6//!
    7//! The [`escape_default`] function provides an iterator over the bytes of an
    8//! escaped version of the character given.
    9
    10#![stable(feature = "core_ascii", since = "1.26.0")]
    11
    12use crate::escape::{AlwaysEscaped, EscapeIterInner};
    13use crate::fmt;
    14use crate::iter::FusedIterator;
    15use crate::num::NonZero;
    16
    17mod ascii_char;
    18#[doc(alias("AsciiChar"))]
    19#[unstable(feature = "ascii_char", issue = "110998")]
    20pub use ascii_char::AsciiChar as Char;
    21
    22/// An iterator over the escaped version of a byte.
    23///
    24/// This `struct` is created by the [`escape_default`] function. See its
    25/// documentation for more.
    26#[must_use = "iterators are lazy and do nothing unless consumed"]
    27#[stable(feature = "rust1", since = "1.0.0")]
    28#[derive(Clone)]
    29pub struct EscapeDefault(EscapeIterInner<4, AlwaysEscaped>);
    30
    31/// Returns an iterator that produces an escaped version of a `u8`.
    32///
    33/// The default is chosen with a bias toward producing literals that are
    34/// legal in a variety of languages, including C++11 and similar C-family
    35/// languages. The exact rules are:
    36///
    37/// * Tab is escaped as `\t`.
    38/// * Carriage return is escaped as `\r`.
    39/// * Line feed is escaped as `\n`.
    40/// * Single quote is escaped as `\'`.
    41/// * Double quote is escaped as `\"`.
    42/// * Backslash is escaped as `\\`.
    43/// * Any character in the 'printable ASCII' range `0x20` .. `0x7e`
    44///   inclusive is not escaped.
    45/// * Any other chars are given hex escapes of the form '\xNN'.
    46/// * Unicode escapes are never generated by this function.
    47///
    48/// # Examples
    49///
    50/// ```
    51/// use std::ascii;
    52///
    53/// let escaped = ascii::escape_default(b'0').next().unwrap();
    54/// assert_eq!(b'0', escaped);
    55///
    56/// let mut escaped = ascii::escape_default(b'\t');
    57///
    58/// assert_eq!(b'\\', escaped.next().unwrap());
    59/// assert_eq!(b't', escaped.next().unwrap());
    60///
    61/// let mut escaped = ascii::escape_default(b'\r');
    62///
    63/// assert_eq!(b'\\', escaped.next().unwrap());
    64/// assert_eq!(b'r', escaped.next().unwrap());
    65///
    66/// let mut escaped = ascii::escape_default(b'\n');
    67///
    68/// assert_eq!(b'\\', escaped.next().unwrap());
    69/// assert_eq!(b'n', escaped.next().unwrap());
    70///
    71/// let mut escaped = ascii::escape_default(b'\'');
    72///
    73/// assert_eq!(b'\\', escaped.next().unwrap());
    74/// assert_eq!(b'\'', escaped.next().unwrap());
    75///
    76/// let mut escaped = ascii::escape_default(b'"');
    77///
    78/// assert_eq!(b'\\', escaped.next().unwrap());
    79/// assert_eq!(b'"', escaped.next().unwrap());
    80///
    81/// let mut escaped = ascii::escape_default(b'\\');
    82///
    83/// assert_eq!(b'\\', escaped.next().unwrap());
    84/// assert_eq!(b'\\', escaped.next().unwrap());
    85///
    86/// let mut escaped = ascii::escape_default(b'\x9d');
    87///
    88/// assert_eq!(b'\\', escaped.next().unwrap());
    89/// assert_eq!(b'x', escaped.next().unwrap());
    90/// assert_eq!(b'9', escaped.next().unwrap());
    91/// assert_eq!(b'd', escaped.next().unwrap());
    92/// ```
    93#[stable(feature = "rust1", since = "1.0.0")]
    94pub fn escape_default(c: u8) -> EscapeDefault {
    95    EscapeDefault::new(c)
    96}
    97
    98impl EscapeDefault {
    99    #[inline]
    100    pub(crate) const fn new(c: u8) -> Self {
    101        Self(EscapeIterInner::ascii(c))
    102    }
    103
    104    #[inline]
    105    pub(crate) fn empty() -> Self {
    106        Self(EscapeIterInner::empty())
    107    }
    108}
    109
    110#[stable(feature = "rust1", since = "1.0.0")]
    111impl Iterator for EscapeDefault {
    112    type Item = u8;
    113
    114    #[inline]
    115    fn next(&mut self) -> Option<u8> {
    116        self.0.next()
    117    }
    118
    119    #[inline]
    120    fn size_hint(&self) -> (usize, Option<usize>) {
    121        let n = self.0.len();
    122        (n, Some(n))
    123    }
    124
    125    #[inline]
    126    fn count(self) -> usize {
    127        self.0.len()
    128    }
    129
    130    #[inline]
    131    fn last(mut self) -> Option<u8> {
    132        self.0.next_back()
    133    }
    134
    135    #[inline]
    136    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
    137        self.0.advance_by(n)
    138    }
    139}
    140
    141#[stable(feature = "rust1", since = "1.0.0")]
    142impl DoubleEndedIterator for EscapeDefault {
    143    #[inline]
    144    fn next_back(&mut self) -> Option<u8> {
    145        self.0.next_back()
    146    }
    147
    148    #[inline]
    149    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
    150        self.0.advance_back_by(n)
    151    }
    152}
    153
    154#[stable(feature = "rust1", since = "1.0.0")]
    155impl ExactSizeIterator for EscapeDefault {
    156    #[inline]
    157    fn len(&self) -> usize {
    158        self.0.len()
    159    }
    160}
    161
    162#[stable(feature = "fused", since = "1.26.0")]
    163impl FusedIterator for EscapeDefault {}
    164
    165#[stable(feature = "ascii_escape_display", since = "1.39.0")]
    166impl fmt::Display for EscapeDefault {
    167    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    168        fmt::Display::fmt(&self.0, f)
    169    }
    170}
    171
    172#[stable(feature = "std_debug", since = "1.16.0")]
    173impl fmt::Debug for EscapeDefault {
    174    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    175        f.debug_struct("EscapeDefault").finish_non_exhaustive()
    176    }
    177}