2018-03-04 12:33:34 -06:00
|
|
|
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
|
|
|
//! Operations on ASCII strings and characters.
|
|
|
|
//!
|
|
|
|
//! Most string operations in Rust act on UTF-8 strings. However, at times it
|
|
|
|
//! makes more sense to only consider the ASCII character set for a specific
|
|
|
|
//! operation.
|
|
|
|
//!
|
|
|
|
//! The [`escape_default`] function provides an iterator over the bytes of an
|
|
|
|
//! escaped version of the character given.
|
|
|
|
//!
|
|
|
|
//! [`escape_default`]: fn.escape_default.html
|
|
|
|
|
2018-03-05 15:39:09 -06:00
|
|
|
#![stable(feature = "core_ascii", since = "1.26.0")]
|
2018-03-04 12:33:34 -06:00
|
|
|
|
|
|
|
use fmt;
|
|
|
|
use ops::Range;
|
|
|
|
use iter::FusedIterator;
|
|
|
|
|
|
|
|
/// An iterator over the escaped version of a byte.
|
|
|
|
///
|
|
|
|
/// This `struct` is created by the [`escape_default`] function. See its
|
|
|
|
/// documentation for more.
|
|
|
|
///
|
|
|
|
/// [`escape_default`]: fn.escape_default.html
|
2018-04-04 18:35:09 -05:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2018-03-04 12:33:34 -06:00
|
|
|
pub struct EscapeDefault {
|
|
|
|
range: Range<usize>,
|
|
|
|
data: [u8; 4],
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns an iterator that produces an escaped version of a `u8`.
|
|
|
|
///
|
|
|
|
/// The default is chosen with a bias toward producing literals that are
|
|
|
|
/// legal in a variety of languages, including C++11 and similar C-family
|
|
|
|
/// languages. The exact rules are:
|
|
|
|
///
|
|
|
|
/// * Tab is escaped as `\t`.
|
|
|
|
/// * Carriage return is escaped as `\r`.
|
|
|
|
/// * Line feed is escaped as `\n`.
|
|
|
|
/// * Single quote is escaped as `\'`.
|
|
|
|
/// * Double quote is escaped as `\"`.
|
|
|
|
/// * Backslash is escaped as `\\`.
|
|
|
|
/// * Any character in the 'printable ASCII' range `0x20` .. `0x7e`
|
|
|
|
/// inclusive is not escaped.
|
|
|
|
/// * Any other chars are given hex escapes of the form '\xNN'.
|
|
|
|
/// * Unicode escapes are never generated by this function.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
2018-03-04 19:32:44 -06:00
|
|
|
/// use std::ascii;
|
2018-03-04 13:39:14 -06:00
|
|
|
///
|
2018-03-04 12:33:34 -06:00
|
|
|
/// let escaped = ascii::escape_default(b'0').next().unwrap();
|
|
|
|
/// assert_eq!(b'0', escaped);
|
|
|
|
///
|
|
|
|
/// let mut escaped = ascii::escape_default(b'\t');
|
|
|
|
///
|
|
|
|
/// assert_eq!(b'\\', escaped.next().unwrap());
|
|
|
|
/// assert_eq!(b't', escaped.next().unwrap());
|
|
|
|
///
|
|
|
|
/// let mut escaped = ascii::escape_default(b'\r');
|
|
|
|
///
|
|
|
|
/// assert_eq!(b'\\', escaped.next().unwrap());
|
|
|
|
/// assert_eq!(b'r', escaped.next().unwrap());
|
|
|
|
///
|
|
|
|
/// let mut escaped = ascii::escape_default(b'\n');
|
|
|
|
///
|
|
|
|
/// assert_eq!(b'\\', escaped.next().unwrap());
|
|
|
|
/// assert_eq!(b'n', escaped.next().unwrap());
|
|
|
|
///
|
|
|
|
/// let mut escaped = ascii::escape_default(b'\'');
|
|
|
|
///
|
|
|
|
/// assert_eq!(b'\\', escaped.next().unwrap());
|
|
|
|
/// assert_eq!(b'\'', escaped.next().unwrap());
|
|
|
|
///
|
|
|
|
/// let mut escaped = ascii::escape_default(b'"');
|
|
|
|
///
|
|
|
|
/// assert_eq!(b'\\', escaped.next().unwrap());
|
|
|
|
/// assert_eq!(b'"', escaped.next().unwrap());
|
|
|
|
///
|
|
|
|
/// let mut escaped = ascii::escape_default(b'\\');
|
|
|
|
///
|
|
|
|
/// assert_eq!(b'\\', escaped.next().unwrap());
|
|
|
|
/// assert_eq!(b'\\', escaped.next().unwrap());
|
|
|
|
///
|
|
|
|
/// let mut escaped = ascii::escape_default(b'\x9d');
|
|
|
|
///
|
|
|
|
/// assert_eq!(b'\\', escaped.next().unwrap());
|
|
|
|
/// assert_eq!(b'x', escaped.next().unwrap());
|
|
|
|
/// assert_eq!(b'9', escaped.next().unwrap());
|
|
|
|
/// assert_eq!(b'd', escaped.next().unwrap());
|
|
|
|
/// ```
|
2018-04-04 18:35:09 -05:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2018-03-04 13:39:14 -06:00
|
|
|
pub fn escape_default(c: u8) -> EscapeDefault {
|
2018-03-04 12:33:34 -06:00
|
|
|
let (data, len) = match c {
|
|
|
|
b'\t' => ([b'\\', b't', 0, 0], 2),
|
|
|
|
b'\r' => ([b'\\', b'r', 0, 0], 2),
|
|
|
|
b'\n' => ([b'\\', b'n', 0, 0], 2),
|
|
|
|
b'\\' => ([b'\\', b'\\', 0, 0], 2),
|
|
|
|
b'\'' => ([b'\\', b'\'', 0, 0], 2),
|
|
|
|
b'"' => ([b'\\', b'"', 0, 0], 2),
|
|
|
|
b'\x20' ... b'\x7e' => ([c, 0, 0, 0], 1),
|
|
|
|
_ => ([b'\\', b'x', hexify(c >> 4), hexify(c & 0xf)], 4),
|
|
|
|
};
|
|
|
|
|
|
|
|
return EscapeDefault { range: 0..len, data };
|
|
|
|
|
|
|
|
fn hexify(b: u8) -> u8 {
|
|
|
|
match b {
|
|
|
|
0 ... 9 => b'0' + b,
|
|
|
|
_ => b'a' + b - 10,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
impl Iterator for EscapeDefault {
|
|
|
|
type Item = u8;
|
|
|
|
fn next(&mut self) -> Option<u8> { self.range.next().map(|i| self.data[i]) }
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() }
|
|
|
|
}
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
impl DoubleEndedIterator for EscapeDefault {
|
|
|
|
fn next_back(&mut self) -> Option<u8> {
|
|
|
|
self.range.next_back().map(|i| self.data[i])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
impl ExactSizeIterator for EscapeDefault {}
|
2018-03-06 15:33:38 -06:00
|
|
|
#[stable(feature = "fused", since = "1.26.0")]
|
2018-03-04 12:33:34 -06:00
|
|
|
impl FusedIterator for EscapeDefault {}
|
|
|
|
|
|
|
|
#[stable(feature = "std_debug", since = "1.16.0")]
|
|
|
|
impl fmt::Debug for EscapeDefault {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.pad("EscapeDefault { .. }")
|
|
|
|
}
|
|
|
|
}
|