about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstd/ffi/os_str.rs18
-rw-r--r--src/libstd/path.rs8
-rw-r--r--src/libstd/sys/redox/os_str.rs27
-rw-r--r--src/libstd/sys/unix/os_str.rs27
-rw-r--r--src/libstd/sys/windows/os_str.rs26
-rw-r--r--src/libstd/sys_common/wtf8.rs46
6 files changed, 117 insertions, 35 deletions
diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index a5a1b5e5f09..f54d79c201f 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use borrow::{Borrow, Cow};
-use fmt::{self, Debug};
+use fmt;
 use mem;
 use ops;
 use cmp;
@@ -312,8 +312,8 @@ impl Default for OsString {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Debug for OsString {
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+impl fmt::Debug for OsString {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         fmt::Debug::fmt(&**self, formatter)
     }
 }
@@ -669,9 +669,15 @@ impl Hash for OsStr {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Debug for OsStr {
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-        self.inner.fmt(formatter)
+impl fmt::Debug for OsStr {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(&self.inner, formatter)
+    }
+}
+
+impl OsStr {
+    pub(crate) fn display(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(&self.inner, formatter)
     }
 }
 
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index e128a4164d7..42a54ed6d75 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -2281,8 +2281,8 @@ impl AsRef<OsStr> for Path {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Debug for Path {
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-        self.inner.fmt(formatter)
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(&self.inner, formatter)
     }
 }
 
@@ -2314,14 +2314,14 @@ pub struct Display<'a> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> fmt::Debug for Display<'a> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Debug::fmt(&self.path.to_string_lossy(), f)
+        fmt::Debug::fmt(&self.path, f)
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> fmt::Display for Display<'a> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Display::fmt(&self.path.to_string_lossy(), f)
+        self.path.inner.display(f)
     }
 }
 
diff --git a/src/libstd/sys/redox/os_str.rs b/src/libstd/sys/redox/os_str.rs
index c2bba07f68c..c54286353a9 100644
--- a/src/libstd/sys/redox/os_str.rs
+++ b/src/libstd/sys/redox/os_str.rs
@@ -12,10 +12,11 @@
 /// a `Vec<u8>`/`[u8]`.
 
 use borrow::Cow;
-use fmt::{self, Debug};
+use fmt;
 use str;
 use mem;
 use sys_common::{AsInner, IntoInner};
+use std_unicode::lossy::Utf8Lossy;
 
 #[derive(Clone, Hash)]
 pub struct Buf {
@@ -26,15 +27,27 @@ pub struct Slice {
     pub inner: [u8]
 }
 
-impl Debug for Slice {
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-        self.to_string_lossy().fmt(formatter)
+impl fmt::Debug for Slice {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter)
     }
 }
 
-impl Debug for Buf {
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-        self.as_slice().fmt(formatter)
+impl fmt::Display for Slice {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter)
+    }
+}
+
+impl fmt::Debug for Buf {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(self.as_slice(), formatter)
+    }
+}
+
+impl fmt::Display for Buf {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(self.as_slice(), formatter)
     }
 }
 
diff --git a/src/libstd/sys/unix/os_str.rs b/src/libstd/sys/unix/os_str.rs
index f5b942d3343..777db17e3e1 100644
--- a/src/libstd/sys/unix/os_str.rs
+++ b/src/libstd/sys/unix/os_str.rs
@@ -12,10 +12,11 @@
 /// a `Vec<u8>`/`[u8]`.
 
 use borrow::Cow;
-use fmt::{self, Debug};
+use fmt;
 use str;
 use mem;
 use sys_common::{AsInner, IntoInner};
+use std_unicode::lossy::Utf8Lossy;
 
 #[derive(Clone, Hash)]
 pub struct Buf {
@@ -26,15 +27,27 @@ pub struct Slice {
     pub inner: [u8]
 }
 
-impl Debug for Slice {
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-        self.to_string_lossy().fmt(formatter)
+impl fmt::Debug for Slice {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter)
     }
 }
 
-impl Debug for Buf {
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-        self.as_slice().fmt(formatter)
+impl fmt::Display for Slice {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter)
+    }
+}
+
+impl fmt::Debug for Buf {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(self.as_slice(), formatter)
+    }
+}
+
+impl fmt::Display for Buf {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(self.as_slice(), formatter)
     }
 }
 
diff --git a/src/libstd/sys/windows/os_str.rs b/src/libstd/sys/windows/os_str.rs
index f401e7b35c8..3eb4582718b 100644
--- a/src/libstd/sys/windows/os_str.rs
+++ b/src/libstd/sys/windows/os_str.rs
@@ -12,7 +12,7 @@
 /// wrapper around the "WTF-8" encoding; see the `wtf8` module for more.
 
 use borrow::Cow;
-use fmt::{self, Debug};
+use fmt;
 use sys_common::wtf8::{Wtf8, Wtf8Buf};
 use mem;
 use sys_common::{AsInner, IntoInner};
@@ -34,9 +34,15 @@ impl AsInner<Wtf8> for Buf {
     }
 }
 
-impl Debug for Buf {
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-        self.as_slice().fmt(formatter)
+impl fmt::Debug for Buf {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(self.as_slice(), formatter)
+    }
+}
+
+impl fmt::Display for Buf {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(self.as_slice(), formatter)
     }
 }
 
@@ -44,9 +50,15 @@ pub struct Slice {
     pub inner: Wtf8
 }
 
-impl Debug for Slice {
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-        self.inner.fmt(formatter)
+impl fmt::Debug for Slice {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(&self.inner, formatter)
+    }
+}
+
+impl fmt::Display for Slice {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(&self.inner, formatter)
     }
 }
 
diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs
index df5e4ef1d88..4e4a6e77d12 100644
--- a/src/libstd/sys_common/wtf8.rs
+++ b/src/libstd/sys_common/wtf8.rs
@@ -39,7 +39,7 @@ use slice;
 use str;
 use sys_common::AsInner;
 
-const UTF8_REPLACEMENT_CHARACTER: &'static [u8] = b"\xEF\xBF\xBD";
+const UTF8_REPLACEMENT_CHARACTER: &'static str = "\u{FFFD}";
 
 /// A Unicode code point: from U+0000 to U+10FFFF.
 ///
@@ -339,7 +339,7 @@ impl Wtf8Buf {
                 Some((surrogate_pos, _)) => {
                     pos = surrogate_pos + 3;
                     self.bytes[surrogate_pos..pos]
-                        .copy_from_slice(UTF8_REPLACEMENT_CHARACTER);
+                        .copy_from_slice(UTF8_REPLACEMENT_CHARACTER.as_bytes());
                 },
                 None => return unsafe { String::from_utf8_unchecked(self.bytes) }
             }
@@ -438,6 +438,30 @@ impl fmt::Debug for Wtf8 {
     }
 }
 
+impl fmt::Display for Wtf8 {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        let wtf8_bytes = &self.bytes;
+        let mut pos = 0;
+        loop {
+            match self.next_surrogate(pos) {
+                Some((surrogate_pos, _)) => {
+                    formatter.write_str(unsafe {
+                        str::from_utf8_unchecked(&wtf8_bytes[pos .. surrogate_pos])
+                    })?;
+                    formatter.write_str(UTF8_REPLACEMENT_CHARACTER)?;
+                    pos = surrogate_pos + 3;
+                },
+                None => {
+                    formatter.write_str(unsafe {
+                        str::from_utf8_unchecked(&wtf8_bytes[pos..])
+                    })?;
+                    return Ok(());
+                }
+            }
+        }
+    }
+}
+
 impl Wtf8 {
     /// Creates a WTF-8 slice from a UTF-8 `&str` slice.
     ///
@@ -516,13 +540,13 @@ impl Wtf8 {
         let wtf8_bytes = &self.bytes;
         let mut utf8_bytes = Vec::with_capacity(self.len());
         utf8_bytes.extend_from_slice(&wtf8_bytes[..surrogate_pos]);
-        utf8_bytes.extend_from_slice(UTF8_REPLACEMENT_CHARACTER);
+        utf8_bytes.extend_from_slice(UTF8_REPLACEMENT_CHARACTER.as_bytes());
         let mut pos = surrogate_pos + 3;
         loop {
             match self.next_surrogate(pos) {
                 Some((surrogate_pos, _)) => {
                     utf8_bytes.extend_from_slice(&wtf8_bytes[pos .. surrogate_pos]);
-                    utf8_bytes.extend_from_slice(UTF8_REPLACEMENT_CHARACTER);
+                    utf8_bytes.extend_from_slice(UTF8_REPLACEMENT_CHARACTER.as_bytes());
                     pos = surrogate_pos + 3;
                 },
                 None => {
@@ -1201,6 +1225,20 @@ mod tests {
     }
 
     #[test]
+    fn wtf8_display() {
+        fn d(b: &[u8]) -> String {
+            format!("{}", &unsafe { Wtf8::from_bytes_unchecked(b) })
+        }
+
+        assert_eq!("", d("".as_bytes()));
+        assert_eq!("aé 💩", d("aé 💩".as_bytes()));
+
+        let mut string = Wtf8Buf::from_str("aé 💩");
+        string.push(CodePoint::from_u32(0xD800).unwrap());
+        assert_eq!("aé 💩�", d(string.as_inner()));
+    }
+
+    #[test]
     fn wtf8_encode_wide() {
         let mut string = Wtf8Buf::from_str("aé ");
         string.push(CodePoint::from_u32(0xD83D).unwrap());