about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTobias Bucher <tobiasbucher5991@gmail.com>2016-07-26 01:39:54 +0200
committerTobias Bucher <tobiasbucher5991@gmail.com>2016-07-26 15:15:00 +0200
commit68efea08fa1cf800b3b76683992ec77a89323d53 (patch)
treef9c7cee686d99efacdf80cbbaf477bd6ff19f12f
parent0685900fbd1ea1f6be5c3454dcde753ac3484c01 (diff)
downloadrust-68efea08fa1cf800b3b76683992ec77a89323d53.tar.gz
rust-68efea08fa1cf800b3b76683992ec77a89323d53.zip
Restore `char::escape_default` and add `char::escape` instead
-rw-r--r--src/libcollections/lib.rs1
-rw-r--r--src/libcollections/str.rs8
-rw-r--r--src/libcollectionstest/str.rs16
-rw-r--r--src/libcore/char.rs38
-rw-r--r--src/libcore/fmt/mod.rs4
-rw-r--r--src/libcoretest/char.rs47
-rw-r--r--src/librustc_unicode/char.rs37
-rw-r--r--src/librustc_unicode/lib.rs1
8 files changed, 145 insertions, 7 deletions
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index f027d074cb6..333219bc5e5 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -33,6 +33,7 @@
 #![feature(allow_internal_unstable)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
+#![feature(char_escape)]
 #![feature(core_intrinsics)]
 #![feature(dropck_parametricity)]
 #![feature(fmt_internals)]
diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs
index 55308a46f0a..a63ea9d3ec7 100644
--- a/src/libcollections/str.rs
+++ b/src/libcollections/str.rs
@@ -1697,6 +1697,14 @@ impl str {
         return s;
     }
 
+    /// Escapes each char in `s` with `char::escape`.
+    #[unstable(feature = "str_escape",
+               reason = "return type may change to be an iterator",
+               issue = "27791")]
+    pub fn escape(&self) -> String {
+        self.chars().flat_map(|c| c.escape()).collect()
+    }
+
     /// Escapes each char in `s` with `char::escape_default`.
     #[unstable(feature = "str_escape",
                reason = "return type may change to be an iterator",
diff --git a/src/libcollectionstest/str.rs b/src/libcollectionstest/str.rs
index 4d85c9d545e..870f8a3a1ec 100644
--- a/src/libcollectionstest/str.rs
+++ b/src/libcollectionstest/str.rs
@@ -704,7 +704,7 @@ fn test_escape_unicode() {
 }
 
 #[test]
-fn test_escape_default() {
+fn test_escape() {
     assert_eq!("abc".escape_default(), "abc");
     assert_eq!("a c".escape_default(), "a c");
     assert_eq!("éèê".escape_default(), "éèê");
@@ -718,6 +718,20 @@ fn test_escape_default() {
 }
 
 #[test]
+fn test_escape_default() {
+    assert_eq!("abc".escape_default(), "abc");
+    assert_eq!("a c".escape_default(), "a c");
+    assert_eq!("éèê".escape_default(), "\\u{e9}\\u{e8}\\u{ea}");
+    assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t");
+    assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\");
+    assert_eq!("\u{7f}\u{ff}".escape_default(), "\\u{7f}\\u{ff}");
+    assert_eq!("\u{100}\u{ffff}".escape_default(), "\\u{100}\\u{ffff}");
+    assert_eq!("\u{10000}\u{10ffff}".escape_default(), "\\u{10000}\\u{10ffff}");
+    assert_eq!("ab\u{200b}".escape_default(), "ab\\u{200b}");
+    assert_eq!("\u{10d4ea}\r".escape_default(), "\\u{10d4ea}\\r");
+}
+
+#[test]
 fn test_total_ord() {
     assert_eq!("1234".cmp("123"), Greater);
     assert_eq!("123".cmp("1234"), Less);
diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index 0d39217bd72..3e435b47110 100644
--- a/src/libcore/char.rs
+++ b/src/libcore/char.rs
@@ -264,6 +264,8 @@ pub trait CharExt {
     fn escape_unicode(self) -> EscapeUnicode;
     #[stable(feature = "core", since = "1.6.0")]
     fn escape_default(self) -> EscapeDefault;
+    #[unstable(feature = "char_escape", issue = "0")]
+    fn escape(self) -> Escape;
     #[stable(feature = "core", since = "1.6.0")]
     fn len_utf8(self) -> usize;
     #[stable(feature = "core", since = "1.6.0")]
@@ -321,10 +323,23 @@ impl CharExt for char {
             '\r' => EscapeDefaultState::Backslash('r'),
             '\n' => EscapeDefaultState::Backslash('n'),
             '\\' | '\'' | '"' => EscapeDefaultState::Backslash(self),
+            '\x20' ... '\x7e' => EscapeDefaultState::Char(self),
+            _ => EscapeDefaultState::Unicode(self.escape_unicode())
+        };
+        EscapeDefault { state: init_state }
+    }
+
+    #[inline]
+    fn escape(self) -> Escape {
+        let init_state = match self {
+            '\t' => EscapeDefaultState::Backslash('t'),
+            '\r' => EscapeDefaultState::Backslash('r'),
+            '\n' => EscapeDefaultState::Backslash('n'),
+            '\\' | '\'' | '"' => EscapeDefaultState::Backslash(self),
             c if is_printable(c) => EscapeDefaultState::Char(c),
             c => EscapeDefaultState::Unicode(c.escape_unicode()),
         };
-        EscapeDefault { state: init_state }
+        Escape(EscapeDefault { state: init_state })
     }
 
     #[inline]
@@ -601,6 +616,27 @@ impl ExactSizeIterator for EscapeDefault {
     }
 }
 
+/// An iterator that yields the literal escape code of a `char`.
+///
+/// This `struct` is created by the [`escape()`] method on [`char`]. See its
+/// documentation for more.
+///
+/// [`escape()`]: ../../std/primitive.char.html#method.escape
+/// [`char`]: ../../std/primitive.char.html
+#[unstable(feature = "char_escape", issue = "0")]
+#[derive(Clone, Debug)]
+pub struct Escape(EscapeDefault);
+
+#[unstable(feature = "char_escape", issue = "0")]
+impl Iterator for Escape {
+    type Item = char;
+    fn next(&mut self) -> Option<char> { self.0.next() }
+    fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() }
+}
+
+#[unstable(feature = "char_escape", issue = "0")]
+impl ExactSizeIterator for Escape { }
+
 /// An iterator over `u8` entries represending the UTF-8 encoding of a `char`
 /// value.
 ///
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index e5eb8f21382..3bcdce57af0 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -1383,7 +1383,7 @@ impl Debug for str {
         f.write_char('"')?;
         let mut from = 0;
         for (i, c) in self.char_indices() {
-            let esc = c.escape_default();
+            let esc = c.escape();
             // If char needs escaping, flush backlog so far and write, else skip
             if esc.len() != 1 {
                 f.write_str(&self[from..i])?;
@@ -1409,7 +1409,7 @@ impl Display for str {
 impl Debug for char {
     fn fmt(&self, f: &mut Formatter) -> Result {
         f.write_char('\'')?;
-        for c in self.escape_default() {
+        for c in self.escape() {
             f.write_char(c)?
         }
         f.write_char('\'')
diff --git a/src/libcoretest/char.rs b/src/libcoretest/char.rs
index e01f83ed70a..ec757b0b5d3 100644
--- a/src/libcoretest/char.rs
+++ b/src/libcoretest/char.rs
@@ -124,9 +124,9 @@ fn test_is_digit() {
 }
 
 #[test]
-fn test_escape_default() {
+fn test_escape() {
     fn string(c: char) -> String {
-        c.escape_default().collect()
+        c.escape().collect()
     }
     let s = string('\n');
     assert_eq!(s, "\\n");
@@ -167,6 +167,49 @@ fn test_escape_default() {
 }
 
 #[test]
+fn test_escape_default() {
+    fn string(c: char) -> String {
+        c.escape_default().collect()
+    }
+    let s = string('\n');
+    assert_eq!(s, "\\n");
+    let s = string('\r');
+    assert_eq!(s, "\\r");
+    let s = string('\'');
+    assert_eq!(s, "\\'");
+    let s = string('"');
+    assert_eq!(s, "\\\"");
+    let s = string(' ');
+    assert_eq!(s, " ");
+    let s = string('a');
+    assert_eq!(s, "a");
+    let s = string('~');
+    assert_eq!(s, "~");
+    let s = string('é');
+    assert_eq!(s, "\\u{e9}");
+    let s = string('\x00');
+    assert_eq!(s, "\\u{0}");
+    let s = string('\x1f');
+    assert_eq!(s, "\\u{1f}");
+    let s = string('\x7f');
+    assert_eq!(s, "\\u{7f}");
+    let s = string('\u{80}');
+    assert_eq!(s, "\\u{80}");
+    let s = string('\u{ff}');
+    assert_eq!(s, "\\u{ff}");
+    let s = string('\u{11b}');
+    assert_eq!(s, "\\u{11b}");
+    let s = string('\u{1d4b6}');
+    assert_eq!(s, "\\u{1d4b6}");
+    let s = string('\u{200b}'); // zero width space
+    assert_eq!(s, "\\u{200b}");
+    let s = string('\u{e000}'); // private use 1
+    assert_eq!(s, "\\u{e000}");
+    let s = string('\u{100000}'); // private use 2
+    assert_eq!(s, "\\u{100000}");
+}
+
+#[test]
 fn test_escape_unicode() {
     fn string(c: char) -> String { c.escape_unicode().collect() }
 
diff --git a/src/librustc_unicode/char.rs b/src/librustc_unicode/char.rs
index 7445ff94eb5..683d5289ab5 100644
--- a/src/librustc_unicode/char.rs
+++ b/src/librustc_unicode/char.rs
@@ -36,7 +36,7 @@ use tables::{conversions, derived_property, general_category, property};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::char::{MAX, from_digit, from_u32, from_u32_unchecked};
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use core::char::{EncodeUtf16, EncodeUtf8, EscapeDefault, EscapeUnicode};
+pub use core::char::{EncodeUtf16, EncodeUtf8, Escape, EscapeDefault, EscapeUnicode};
 
 // unstable reexports
 #[unstable(feature = "decode_utf8", issue = "33906")]
@@ -269,6 +269,41 @@ impl char {
 
     /// Returns an iterator that yields the literal escape code of a `char`.
     ///
+    /// This will escape the characters similar to the `Debug` implementations
+    /// of `str` or `char`.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// for i in '\n'.escape_default() {
+    ///     println!("{}", i);
+    /// }
+    /// ```
+    ///
+    /// This prints:
+    ///
+    /// ```text
+    /// \
+    /// n
+    /// ```
+    ///
+    /// Collecting into a `String`:
+    ///
+    /// ```
+    /// let quote: String = '\n'.escape_default().collect();
+    ///
+    /// assert_eq!(quote, "\\n");
+    /// ```
+    #[unstable(feature = "char_escape", issue = "0")]
+    #[inline]
+    pub fn escape(self) -> Escape {
+        C::escape(self)
+    }
+
+    /// Returns an iterator that yields the literal escape code of a `char`.
+    ///
     /// 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:
diff --git a/src/librustc_unicode/lib.rs b/src/librustc_unicode/lib.rs
index f91a754ab57..8c91d3b6a92 100644
--- a/src/librustc_unicode/lib.rs
+++ b/src/librustc_unicode/lib.rs
@@ -32,6 +32,7 @@
 #![cfg_attr(not(stage0), deny(warnings))]
 #![no_std]
 
+#![feature(char_escape)]
 #![feature(core_char_ext)]
 #![feature(decode_utf8)]
 #![feature(lang_items)]