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
This commit is contained in:
Alex Crichton 2014-12-12 10:59:41 -08:00
parent cd614164e6
commit e423fcf0e0
25 changed files with 320 additions and 359 deletions

View file

@ -995,9 +995,11 @@ pub trait ToString {
impl<T: fmt::Show> ToString for T {
fn to_string(&self) -> String {
let mut buf = Vec::<u8>::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::*;