Skip to content

Commit c290857

Browse files
committed
Auto merge of #48735 - 1011X:master, r=alexcrichton
Move ascii::escape_default to libcore As requested in #46409, the `ascii::escape_default` method has been added to the core library. All I did was copy over the `std::ascii` module file, remove the (redundant) `AsciiExt` trait, and change some of the documentation to match. None of the tests were changed. I wasn't sure how to handle the annotations. For `EscapeDefault` and `escape_default()`, I changed them to `#[unstable(feature = "core_ascii", issue = "46409")]`. Is that alright? Or should I leave them as they were?
2 parents 8c4ff22 + 1a16271 commit c290857

File tree

5 files changed

+512
-477
lines changed

5 files changed

+512
-477
lines changed

src/libcore/ascii.rs

+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! Operations on ASCII strings and characters.
12+
//!
13+
//! Most string operations in Rust act on UTF-8 strings. However, at times it
14+
//! makes more sense to only consider the ASCII character set for a specific
15+
//! operation.
16+
//!
17+
//! The [`escape_default`] function provides an iterator over the bytes of an
18+
//! escaped version of the character given.
19+
//!
20+
//! [`escape_default`]: fn.escape_default.html
21+
22+
#![stable(feature = "core_ascii", since = "1.26.0")]
23+
24+
use fmt;
25+
use ops::Range;
26+
use iter::FusedIterator;
27+
28+
/// An iterator over the escaped version of a byte.
29+
///
30+
/// This `struct` is created by the [`escape_default`] function. See its
31+
/// documentation for more.
32+
///
33+
/// [`escape_default`]: fn.escape_default.html
34+
#[stable(feature = "core_ascii", since = "1.26.0")]
35+
pub struct EscapeDefault {
36+
range: Range<usize>,
37+
data: [u8; 4],
38+
}
39+
40+
/// Returns an iterator that produces an escaped version of a `u8`.
41+
///
42+
/// The default is chosen with a bias toward producing literals that are
43+
/// legal in a variety of languages, including C++11 and similar C-family
44+
/// languages. The exact rules are:
45+
///
46+
/// * Tab is escaped as `\t`.
47+
/// * Carriage return is escaped as `\r`.
48+
/// * Line feed is escaped as `\n`.
49+
/// * Single quote is escaped as `\'`.
50+
/// * Double quote is escaped as `\"`.
51+
/// * Backslash is escaped as `\\`.
52+
/// * Any character in the 'printable ASCII' range `0x20` .. `0x7e`
53+
/// inclusive is not escaped.
54+
/// * Any other chars are given hex escapes of the form '\xNN'.
55+
/// * Unicode escapes are never generated by this function.
56+
///
57+
/// # Examples
58+
///
59+
/// ```
60+
/// use std::ascii;
61+
///
62+
/// let escaped = ascii::escape_default(b'0').next().unwrap();
63+
/// assert_eq!(b'0', escaped);
64+
///
65+
/// let mut escaped = ascii::escape_default(b'\t');
66+
///
67+
/// assert_eq!(b'\\', escaped.next().unwrap());
68+
/// assert_eq!(b't', escaped.next().unwrap());
69+
///
70+
/// let mut escaped = ascii::escape_default(b'\r');
71+
///
72+
/// assert_eq!(b'\\', escaped.next().unwrap());
73+
/// assert_eq!(b'r', escaped.next().unwrap());
74+
///
75+
/// let mut escaped = ascii::escape_default(b'\n');
76+
///
77+
/// assert_eq!(b'\\', escaped.next().unwrap());
78+
/// assert_eq!(b'n', 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'"');
86+
///
87+
/// assert_eq!(b'\\', escaped.next().unwrap());
88+
/// assert_eq!(b'"', escaped.next().unwrap());
89+
///
90+
/// let mut escaped = ascii::escape_default(b'\\');
91+
///
92+
/// assert_eq!(b'\\', escaped.next().unwrap());
93+
/// assert_eq!(b'\\', escaped.next().unwrap());
94+
///
95+
/// let mut escaped = ascii::escape_default(b'\x9d');
96+
///
97+
/// assert_eq!(b'\\', escaped.next().unwrap());
98+
/// assert_eq!(b'x', escaped.next().unwrap());
99+
/// assert_eq!(b'9', escaped.next().unwrap());
100+
/// assert_eq!(b'd', escaped.next().unwrap());
101+
/// ```
102+
#[stable(feature = "core_ascii", since = "1.26.0")]
103+
pub fn escape_default(c: u8) -> EscapeDefault {
104+
let (data, len) = match c {
105+
b'\t' => ([b'\\', b't', 0, 0], 2),
106+
b'\r' => ([b'\\', b'r', 0, 0], 2),
107+
b'\n' => ([b'\\', b'n', 0, 0], 2),
108+
b'\\' => ([b'\\', b'\\', 0, 0], 2),
109+
b'\'' => ([b'\\', b'\'', 0, 0], 2),
110+
b'"' => ([b'\\', b'"', 0, 0], 2),
111+
b'\x20' ... b'\x7e' => ([c, 0, 0, 0], 1),
112+
_ => ([b'\\', b'x', hexify(c >> 4), hexify(c & 0xf)], 4),
113+
};
114+
115+
return EscapeDefault { range: 0..len, data };
116+
117+
fn hexify(b: u8) -> u8 {
118+
match b {
119+
0 ... 9 => b'0' + b,
120+
_ => b'a' + b - 10,
121+
}
122+
}
123+
}
124+
125+
#[stable(feature = "rust1", since = "1.0.0")]
126+
impl Iterator for EscapeDefault {
127+
type Item = u8;
128+
fn next(&mut self) -> Option<u8> { self.range.next().map(|i| self.data[i]) }
129+
fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() }
130+
}
131+
#[stable(feature = "rust1", since = "1.0.0")]
132+
impl DoubleEndedIterator for EscapeDefault {
133+
fn next_back(&mut self) -> Option<u8> {
134+
self.range.next_back().map(|i| self.data[i])
135+
}
136+
}
137+
#[stable(feature = "rust1", since = "1.0.0")]
138+
impl ExactSizeIterator for EscapeDefault {}
139+
#[stable(feature = "fused", since = "1.26.0")]
140+
impl FusedIterator for EscapeDefault {}
141+
142+
#[stable(feature = "std_debug", since = "1.16.0")]
143+
impl fmt::Debug for EscapeDefault {
144+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
145+
f.pad("EscapeDefault { .. }")
146+
}
147+
}

src/libcore/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ pub mod borrow;
167167

168168
pub mod any;
169169
pub mod array;
170+
pub mod ascii;
170171
pub mod sync;
171172
pub mod cell;
172173
pub mod char;

0 commit comments

Comments
 (0)