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;
13use crate::fmt;
14use crate::iter::FusedIterator;
15use crate::num::NonZeroUsize;
16
17mod ascii_char;
18#[unstable(feature = "ascii_char", issue = "110998")]
19pub use ascii_char::AsciiChar as Char;
20
21/// An iterator over the escaped version of a byte.
22///
23/// This `struct` is created by the [`escape_default`] function. See its
24/// documentation for more.
25#[must_use = "iterators are lazy and do nothing unless consumed"]
26#[stable(feature = "rust1", since = "1.0.0")]
27#[derive(Clone)]
28pub struct EscapeDefault(escape::EscapeIterInner<4>);
29
30/// Returns an iterator that produces an escaped version of a `u8`.
31///
32/// The default is chosen with a bias toward producing literals that are
33/// legal in a variety of languages, including C++11 and similar C-family
34/// languages. The exact rules are:
35///
36/// * Tab is escaped as `\t`.
37/// * Carriage return is escaped as `\r`.
38/// * Line feed is escaped as `\n`.
39/// * Single quote is escaped as `\'`.
40/// * Double quote is escaped as `\"`.
41/// * Backslash is escaped as `\\`.
42/// * Any character in the 'printable ASCII' range `0x20` .. `0x7e`
43/// inclusive is not escaped.
44/// * Any other chars are given hex escapes of the form '\xNN'.
45/// * Unicode escapes are never generated by this function.
46///
47/// # Examples
48///
49/// ```
50/// use std::ascii;
51///
52/// let escaped = ascii::escape_default(b'0').next().unwrap();
53/// assert_eq!(b'0', escaped);
54///
55/// let mut escaped = ascii::escape_default(b'\t');
56///
57/// assert_eq!(b'\\', escaped.next().unwrap());
58/// assert_eq!(b't', escaped.next().unwrap());
59///
60/// let mut escaped = ascii::escape_default(b'\r');
61///
62/// assert_eq!(b'\\', escaped.next().unwrap());
63/// assert_eq!(b'r', escaped.next().unwrap());
64///
65/// let mut escaped = ascii::escape_default(b'\n');
66///
67/// assert_eq!(b'\\', escaped.next().unwrap());
68/// assert_eq!(b'n', escaped.next().unwrap());
69///
70/// let mut escaped = ascii::escape_default(b'\'');
71///
72/// assert_eq!(b'\\', escaped.next().unwrap());
73/// assert_eq!(b'\'', escaped.next().unwrap());
74///
75/// let mut escaped = ascii::escape_default(b'"');
76///
77/// assert_eq!(b'\\', escaped.next().unwrap());
78/// assert_eq!(b'"', escaped.next().unwrap());
79///
80/// let mut escaped = ascii::escape_default(b'\\');
81///
82/// assert_eq!(b'\\', escaped.next().unwrap());
83/// assert_eq!(b'\\', escaped.next().unwrap());
84///
85/// let mut escaped = ascii::escape_default(b'\x9d');
86///
87/// assert_eq!(b'\\', escaped.next().unwrap());
88/// assert_eq!(b'x', escaped.next().unwrap());
89/// assert_eq!(b'9', escaped.next().unwrap());
90/// assert_eq!(b'd', escaped.next().unwrap());
91/// ```
92#[stable(feature = "rust1", since = "1.0.0")]
93pub fn escape_default(c: u8) -> EscapeDefault {
94 let mut data: [AsciiChar; 4] = [Char::Null; 4];
95 let range: Range = escape::escape_ascii_into(&mut data, byte:c);
96 EscapeDefault(escape::EscapeIterInner::new(data, alive:range))
97}
98
99impl EscapeDefault {
100 pub(crate) fn empty() -> Self {
101 let data: [AsciiChar; 4] = [Char::Null; 4];
102 EscapeDefault(escape::EscapeIterInner::new(data, alive:0..0))
103 }
104
105 pub(crate) fn as_str(&self) -> &str {
106 self.0.as_str()
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<(), NonZeroUsize> {
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<(), NonZeroUsize> {
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 f.write_str(self.0.as_str())
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(name:"EscapeDefault").finish_non_exhaustive()
176 }
177}
178