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.
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.
11 //! Operations on ASCII strings and characters.
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
17 //! The [`escape_default`] function provides an iterator over the bytes of an
18 //! escaped version of the character given.
20 //! [`escape_default`]: fn.escape_default.html
22 #![stable(feature = "core_ascii", since = "1.26.0")]
26 use iter::FusedIterator;
28 /// An iterator over the escaped version of a byte.
30 /// This `struct` is created by the [`escape_default`] function. See its
31 /// documentation for more.
33 /// [`escape_default`]: fn.escape_default.html
34 #[stable(feature = "rust1", since = "1.0.0")]
35 pub struct EscapeDefault {
40 /// Returns an iterator that produces an escaped version of a `u8`.
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:
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.
62 /// let escaped = ascii::escape_default(b'0').next().unwrap();
63 /// assert_eq!(b'0', escaped);
65 /// let mut escaped = ascii::escape_default(b'\t');
67 /// assert_eq!(b'\\', escaped.next().unwrap());
68 /// assert_eq!(b't', escaped.next().unwrap());
70 /// let mut escaped = ascii::escape_default(b'\r');
72 /// assert_eq!(b'\\', escaped.next().unwrap());
73 /// assert_eq!(b'r', escaped.next().unwrap());
75 /// let mut escaped = ascii::escape_default(b'\n');
77 /// assert_eq!(b'\\', escaped.next().unwrap());
78 /// assert_eq!(b'n', escaped.next().unwrap());
80 /// let mut escaped = ascii::escape_default(b'\'');
82 /// assert_eq!(b'\\', escaped.next().unwrap());
83 /// assert_eq!(b'\'', escaped.next().unwrap());
85 /// let mut escaped = ascii::escape_default(b'"');
87 /// assert_eq!(b'\\', escaped.next().unwrap());
88 /// assert_eq!(b'"', escaped.next().unwrap());
90 /// let mut escaped = ascii::escape_default(b'\\');
92 /// assert_eq!(b'\\', escaped.next().unwrap());
93 /// assert_eq!(b'\\', escaped.next().unwrap());
95 /// let mut escaped = ascii::escape_default(b'\x9d');
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());
102 #[stable(feature = "rust1", since = "1.0.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),
115 return EscapeDefault { range: 0..len, data };
117 fn hexify(b: u8) -> u8 {
125 #[stable(feature = "rust1", since = "1.0.0")]
126 impl Iterator for EscapeDefault {
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() }
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])
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 {}
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 { .. }")