about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-10-02 22:49:37 +0000
committerbors <bors@rust-lang.org>2015-10-02 22:49:37 +0000
commitbfb26033af68949646081429040db606a044db22 (patch)
tree312d5abd0a61c9971eef77f3ce82cc369bd33b98 /src/libcore
parent669fc7f7d12b85c8da6e0b0cfe2de0c31dc3d47f (diff)
parent0294098d8f3e2926cf0e6adba9a96e47099c3c0f (diff)
downloadrust-bfb26033af68949646081429040db606a044db22.tar.gz
rust-bfb26033af68949646081429040db606a044db22.zip
Auto merge of #28662 - semmaz:fmt-debug, r=alexcrichton
fixes #26920
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/char.rs31
-rw-r--r--src/libcore/fmt/mod.rs23
2 files changed, 43 insertions, 11 deletions
diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index dfcbfd476bc..ccce2ad22dd 100644
--- a/src/libcore/char.rs
+++ b/src/libcore/char.rs
@@ -185,9 +185,7 @@ impl CharExt for char {
             '\t' => EscapeDefaultState::Backslash('t'),
             '\r' => EscapeDefaultState::Backslash('r'),
             '\n' => EscapeDefaultState::Backslash('n'),
-            '\\' => EscapeDefaultState::Backslash('\\'),
-            '\'' => EscapeDefaultState::Backslash('\''),
-            '"'  => EscapeDefaultState::Backslash('"'),
+            '\\' | '\'' | '"' => EscapeDefaultState::Backslash(self),
             '\x20' ... '\x7e' => EscapeDefaultState::Char(self),
             _ => EscapeDefaultState::Unicode(self.escape_unicode())
         };
@@ -344,6 +342,22 @@ impl Iterator for EscapeUnicode {
             EscapeUnicodeState::Done => None,
         }
     }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let mut n = 0;
+        while (self.c as usize) >> (4 * (n + 1)) != 0 {
+            n += 1;
+        }
+        let n = match self.state {
+            EscapeUnicodeState::Backslash => n + 5,
+            EscapeUnicodeState::Type => n + 4,
+            EscapeUnicodeState::LeftBrace => n + 3,
+            EscapeUnicodeState::Value(offset) => offset + 2,
+            EscapeUnicodeState::RightBrace => 1,
+            EscapeUnicodeState::Done => 0,
+        };
+        (n, Some(n))
+    }
 }
 
 /// An iterator over the characters that represent a `char`, escaped
@@ -377,7 +391,16 @@ impl Iterator for EscapeDefault {
                 Some(c)
             }
             EscapeDefaultState::Done => None,
-            EscapeDefaultState::Unicode(ref mut iter) => iter.next()
+            EscapeDefaultState::Unicode(ref mut iter) => iter.next(),
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        match self.state {
+            EscapeDefaultState::Char(_) => (1, Some(1)),
+            EscapeDefaultState::Backslash(_) => (2, Some(2)),
+            EscapeDefaultState::Unicode(ref iter) => iter.size_hint(),
+            EscapeDefaultState::Done => (0, Some(0)),
         }
     }
 }
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 69fa0fa1609..f6053a75f1f 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -1332,11 +1332,21 @@ impl Display for bool {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Debug for str {
     fn fmt(&self, f: &mut Formatter) -> Result {
-        try!(write!(f, "\""));
-        for c in self.chars().flat_map(|c| c.escape_default()) {
-            try!(f.write_char(c))
+        try!(f.write_char('"'));
+        let mut from = 0;
+        for (i, c) in self.char_indices() {
+            let esc = c.escape_default();
+            // If char needs escaping, flush backlog so far and write, else skip
+            if esc.size_hint() != (1, Some(1)) {
+                try!(f.write_str(&self[from..i]));
+                for c in esc {
+                    try!(f.write_char(c));
+                }
+                from = i + c.len_utf8();
+            }
         }
-        write!(f, "\"")
+        try!(f.write_str(&self[from..]));
+        f.write_char('"')
     }
 }
 
@@ -1350,12 +1360,11 @@ impl Display for str {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Debug for char {
     fn fmt(&self, f: &mut Formatter) -> Result {
-        use char::CharExt;
-        try!(write!(f, "'"));
+        try!(f.write_char('\''));
         for c in self.escape_default() {
             try!(f.write_char(c))
         }
-        write!(f, "'")
+        f.write_char('\'')
     }
 }