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}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy