Deprecate the TextWriter trait in favor of std::fmt::Write.

This commit is contained in:
Simon Sapin
2015-04-21 14:58:12 +02:00
parent 0a0a9ccb3b
commit 1c2d0894af
3 changed files with 8 additions and 194 deletions
+5 -62
View File
@@ -117,69 +117,12 @@ fn defibrillate_flux_capacitor(gigowatts: float) {
# The `TextWriter` trait
[RFC #57](https://github.com/rust-lang/rfcs/pull/57).
Also related: [RFC #526](https://github.com/rust-lang/rfcs/pull/526).
Depreacted. Use [`std::fmt::Write`](http://doc.rust-lang.org/nightly/std/fmt/trait.Write.html) instead.
The [`std::io`](http://doc.rust-lang.org/std/io/index.html) module provides
`Reader` and `Writer` trait that represent generic byte streams,
just like `Iterator<T>` represents arbitrary generic sequences.
Standardizing of these traits allows producers, adaptors, and consumers of data
to interoperate without writing a lot of glue code.
Similarly, it would be useful to have "standard" traits to represent generic streams
where the data is statically enforced to be valid Unicode
(as it is in the `str`, `String`, and `char` types.)
**Note:** [RFC #57](https://github.com/rust-lang/rfcs/pull/57)
proposes two `TextReader` and `TextWriter` traits
that are the Unicode equivalents of `std::io::Reader` and `std::io::Writer`, respectively.
Only `TextWriter` is included here.
The design of `TextReader` is not obvious
since Rust has no direct Unicode equivalent to writing to a pre-allocated `&mut [u8]` slice
and needs some more work.
To use `TextWriter`, add to your `Cargo.toml`:
```toml
[dependencies]
text_writer = "0.1"
```
Example:
```rust
extern crate text_writer;
use text_writer::TextWriter;
struct Ucs4 {
chars: Vec<char>,
}
impl TextWriter for Ucs4 {
#[inline]
fn write_str(&mut self, s: &str) -> Result {
self.chars.extend(s.chars());
Ok(())
}
#[inline]
fn write_char(&mut self, c: char) -> Result {
self.chars.push(c);
Ok(())
}
}
fn write_to<W: TextWriter>(writer: &mut W) -> Result {
try!(writer.write_str("fo"));
writer.write_char('ô')
}
fn main() {
let mut s = Ucs4 { chars: vec![] };
write_to(&mut s).unwrap();
assert_eq!(s.chars.as_slice(), ['f', 'o', 'ô'].as_slice());
}
```
For historical interest, see the [previous README entry](
https://github.com/SimonSapin/rust-std-candidates/tree/0a0a9ccb3b3#the-textwriter-trait)
and [previous code](
https://github.com/SimonSapin/rust-std-candidates/blob/0a0a9ccb3b/text_writer/lib.rs)
# The `return_if_ok!` macro
+2 -2
View File
@@ -1,10 +1,10 @@
[package]
name = "text_writer"
version = "0.1.10"
version = "0.1.11"
authors = ["Simon Sapin <simon.sapin@exyr.org>"]
license = "MIT"
repository = "https://github.com/SimonSapin/rust-std-candidates"
description = "An equivalent to `std::io::Writer` for Unicode text."
description = "Depreacted. Use `std::fmt::Write` instead."
[lib]
+1 -130
View File
@@ -1,130 +1 @@
use std::fmt::{self, Write};
use std::io::Write as IoWrite;
use std::mem;
/// Indicates some kind of error during writing, but does not provide further details.
#[derive(Copy, Clone, Debug)]
pub struct Error;
/// The return type of `TextWriter::write_*` methods.
pub type Result = ::std::result::Result<(), Error>;
/// A Unicode write-only stream.
pub trait TextWriter {
/// Write a string.
///
/// A mininmal implementation can have only this method.
fn write_str(&mut self, s: &str) -> Result;
/// Write a code point.
///
/// A default implementation based on `write_str` is provided,
/// but it is recommended to override it if it can be done more efficiently.
fn write_char(&mut self, c: char) -> Result {
let mut utf_8 = [0u8; 4];
let bytes_written = {
let mut buffer = &mut utf_8[..];
write!(buffer, "{}", c).unwrap();
4 - buffer.len()
};
self.write_str(unsafe { mem::transmute(&utf_8[..bytes_written]) })
}
/// Make `TextWriter` usable with the `write!` macro.
///
/// This typically should not be overridden
fn write_fmt(&mut self, args: fmt::Arguments) -> Result {
struct Adaptor<'a, W: ?Sized + 'a> {
text_writer: &'a mut W,
}
impl<'a, W: ?Sized> fmt::Write for Adaptor<'a, W> where W: TextWriter {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.text_writer.write_str(s).map_err(|_| fmt::Error)
}
}
Adaptor { text_writer: self }.write_fmt(args).map_err(|_| Error)
}
}
impl TextWriter for String {
#[inline]
fn write_str(&mut self, s: &str) -> Result {
self.push_str(s);
Ok(())
}
#[inline]
fn write_char(&mut self, c: char) -> Result {
self.push(c);
Ok(())
}
}
impl<'a> TextWriter for fmt::Formatter<'a> {
#[inline]
fn write_str(&mut self, s: &str) -> Result {
self.write_str(s).map_err(|_| Error)
}
#[inline]
fn write_char(&mut self, c: char) -> Result {
(write!(self, "{}", c)).map_err(|_| Error)
}
}
#[cfg(test)]
fn write_to<W: TextWriter>(dest: &mut W) -> Result {
try!(dest.write_str("fo"));
try!(dest.write_char('ô'));
try!(write!(dest, "{}", 42u32));
Ok(())
}
#[test]
fn test_string() {
let mut s = String::new();
write_to(&mut s).unwrap();
assert_eq!(s, "foô42");
}
#[test]
fn test_fmt_display() {
struct Foo;
impl fmt::Display for Foo {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write_to(formatter).unwrap();
Ok(())
}
}
assert_eq!(Foo.to_string(), "foô42");
}
#[test]
fn test_ucs4() {
struct Ucs4 {
chars: Vec<char>,
}
impl TextWriter for Ucs4 {
#[inline]
fn write_str(&mut self, s: &str) -> Result {
self.chars.extend(s.chars());
Ok(())
}
#[inline]
fn write_char(&mut self, c: char) -> Result {
self.chars.push(c);
Ok(())
}
}
let mut s = Ucs4 { chars: vec![] };
write_to(&mut s).unwrap();
assert_eq!(s.chars, ['f', 'o', 'ô', '4', '2']);
}
//! Depreacted. Use `std::fmt::Write` instead.