From e423fcf0e0166da55f88233e0be5eacba55bc0bc Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 12 Dec 2014 10:59:41 -0800 Subject: std: Enforce Unicode in fmt::Writer This commit is an implementation of [RFC 526][rfc] which is a change to alter the definition of the old `fmt::FormatWriter`. The new trait, renamed to `Writer`, now only exposes one method `write_str` in order to guarantee that all implementations of the formatting traits can only produce valid Unicode. [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0526-fmt-text-writer.md One of the primary improvements of this patch is the performance of the `.to_string()` method by avoiding an almost-always redundant UTF-8 check. This is a breaking change due to the renaming of the trait as well as the loss of the `write` method, but migration paths should be relatively easy: * All usage of `write` should move to `write_str`. If truly binary data was being written in an implementation of `Show`, then it will need to use a different trait or an altogether different code path. * All usage of `write!` should continue to work as-is with no modifications. * All usage of `Show` where implementations just delegate to another should continue to work as-is. [breaking-change] Closes #20352 --- src/libcollections/string.rs | 15 ++++++++++++--- src/libcollections/vec.rs | 6 +++--- 2 files changed, 15 insertions(+), 6 deletions(-) (limited to 'src/libcollections') diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 37a6e690f5d..74b698361f2 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -995,9 +995,11 @@ pub trait ToString { impl ToString for T { fn to_string(&self) -> String { - let mut buf = Vec::::new(); - let _ = fmt::write(&mut buf, format_args!("{}", *self)); - String::from_utf8(buf).unwrap() + use core::fmt::Writer; + let mut buf = String::new(); + let _ = buf.write_fmt(format_args!("{}", self)); + buf.shrink_to_fit(); + buf } } @@ -1073,6 +1075,13 @@ impl<'a> Str for CowString<'a> { } } +impl fmt::Writer for String { + fn write_str(&mut self, s: &str) -> fmt::Result { + self.push_str(s); + Ok(()) + } +} + #[cfg(test)] mod tests { use prelude::*; diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index a1952352bad..a83e35a945d 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1488,9 +1488,9 @@ impl fmt::Show for Vec { } } -impl<'a> fmt::FormatWriter for Vec { - fn write(&mut self, buf: &[u8]) -> fmt::Result { - self.push_all(buf); +impl<'a> fmt::Writer for Vec { + fn write_str(&mut self, s: &str) -> fmt::Result { + self.push_all(s.as_bytes()); Ok(()) } } -- cgit 1.4.1-3-g733a5