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