]> git.lizzy.rs Git - rust.git/commitdiff
std: Stabilize the `io` module
authorAlex Crichton <alex@alexcrichton.com>
Wed, 11 Mar 2015 21:16:46 +0000 (14:16 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Fri, 13 Mar 2015 03:39:03 +0000 (20:39 -0700)
The new `std::io` module has had some time to bake now, and this commit
stabilizes its functionality. There are still portions of the module which
remain unstable, and below contains a summart of the actions taken.

This commit also deprecates the entire contents of the `old_io` module in a
blanket fashion. All APIs should now have a reasonable replacement in the
new I/O modules.

Stable APIs:

* `std::io` (the name)
* `std::io::prelude` (the name)
* `Read`
* `Read::read`
* `Read::{read_to_end, read_to_string}` after being modified to return a `usize`
  for the number of bytes read.
* `Write`
* `Write::write`
* `Write::{write_all, write_fmt}`
* `BufRead`
* `BufRead::{fill_buf, consume}`
* `BufRead::{read_line, read_until}` after being modified to return a `usize`
  for the number of bytes read.
* `BufReader`
* `BufReader::{new, with_capacity}`
* `BufReader::{get_ref, get_mut, into_inner}`
* `{Read,BufRead} for BufReader`
* `BufWriter`
* `BufWriter::{new, with_capacity}`
* `BufWriter::{get_ref, get_mut, into_inner}`
* `Write for BufWriter`
* `IntoInnerError`
* `IntoInnerError::{error, into_inner}`
* `{Error,Display} for IntoInnerError`
* `LineWriter`
* `LineWriter::{new, with_capacity}` - `with_capacity` was added
* `LineWriter::{get_ref, get_mut, into_inner}` - `get_mut` was added)
* `Write for LineWriter`
* `BufStream`
* `BufStream::{new, with_capacities}`
* `BufStream::{get_ref, get_mut, into_inner}`
* `{BufRead,Read,Write} for BufStream`
* `stdin`
* `Stdin`
* `Stdin::lock`
* `Stdin::read_line` - added method
* `StdinLock`
* `Read for Stdin`
* `{Read,BufRead} for StdinLock`
* `stdout`
* `Stdout`
* `Stdout::lock`
* `StdoutLock`
* `Write for Stdout`
* `Write for StdoutLock`
* `stderr`
* `Stderr`
* `Stderr::lock`
* `StderrLock`
* `Write for Stderr`
* `Write for StderrLock`
* `io::Result`
* `io::Error`
* `io::Error::last_os_error`
* `{Display, Error} for Error`

Unstable APIs:

(reasons can be found in the commit itself)

* `Write::flush`
* `Seek`
* `ErrorKind`
* `Error::new`
* `Error::from_os_error`
* `Error::kind`

Deprecated APIs

* `Error::description` - available via the `Error` trait
* `Error::detail` - available via the `Display` implementation
* `thread::Builder::{stdout, stderr}`

Changes in functionality:

* `old_io::stdio::set_stderr` is now a noop as the infrastructure for printing
  backtraces has migrated to `std::io`.
* The `ReadExt`, `WriteExt`, and `BufReadExt` extension traits were all removed
  by folding functionality into the corresponding trait.

[breaking-change]

src/libstd/io/buffered.rs
src/libstd/io/error.rs
src/libstd/io/impls.rs
src/libstd/io/mod.rs
src/libstd/io/prelude.rs
src/libstd/io/stdio.rs
src/libstd/old_io/mod.rs
src/libstd/thread.rs

index 3603f1275048d9fda1fe4210f1ad32f0ba7b9db7..fb7af1d821d2d0944f02c775d3b50a65280000f1 100644 (file)
@@ -16,8 +16,7 @@
 use io::prelude::*;
 
 use cmp;
-use error::Error as StdError;
-use error::FromError;
+use error::{self, FromError};
 use fmt;
 use io::{self, Cursor, DEFAULT_BUF_SIZE, Error, ErrorKind};
 use ptr;
@@ -28,6 +27,7 @@
 /// For example, every call to `read` on `TcpStream` results in a system call.
 /// A `BufReader` performs large, infrequent reads on the underlying `Read`
 /// and maintains an in-memory buffer of the results.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct BufReader<R> {
     inner: R,
     buf: Cursor<Vec<u8>>,
@@ -35,11 +35,13 @@ pub struct BufReader<R> {
 
 impl<R: Read> BufReader<R> {
     /// Creates a new `BufReader` with a default buffer capacity
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(inner: R) -> BufReader<R> {
         BufReader::with_capacity(DEFAULT_BUF_SIZE, inner)
     }
 
     /// Creates a new `BufReader` with the specified buffer capacity
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_capacity(cap: usize, inner: R) -> BufReader<R> {
         BufReader {
             inner: inner,
@@ -48,6 +50,7 @@ pub fn with_capacity(cap: usize, inner: R) -> BufReader<R> {
     }
 
     /// Gets a reference to the underlying reader.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_ref(&self) -> &R { &self.inner }
 
     /// Gets a mutable reference to the underlying reader.
@@ -55,14 +58,17 @@ pub fn get_ref(&self) -> &R { &self.inner }
     /// # Warning
     ///
     /// It is inadvisable to directly read from the underlying reader.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut R { &mut self.inner }
 
     /// Unwraps this `BufReader`, returning the underlying reader.
     ///
     /// Note that any leftover data in the internal buffer is lost.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_inner(self) -> R { self.inner }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<R: Read> Read for BufReader<R> {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         // If we don't have any buffered data and we're doing a massive read
@@ -77,6 +83,7 @@ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<R: Read> BufRead for BufReader<R> {
     fn fill_buf(&mut self) -> io::Result<&[u8]> {
         // If we've reached the end of our internal buffer then we need to fetch
@@ -112,6 +119,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 /// underlying `Write` in large, infrequent batches.
 ///
 /// This writer will be flushed when it is dropped.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct BufWriter<W> {
     inner: Option<W>,
     buf: Vec<u8>,
@@ -120,15 +128,18 @@ pub struct BufWriter<W> {
 /// An error returned by `into_inner` which indicates whether a flush error
 /// happened or not.
 #[derive(Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct IntoInnerError<W>(W, Error);
 
 impl<W: Write> BufWriter<W> {
     /// Creates a new `BufWriter` with a default buffer capacity
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(inner: W) -> BufWriter<W> {
         BufWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
     }
 
     /// Creates a new `BufWriter` with the specified buffer capacity
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_capacity(cap: usize, inner: W) -> BufWriter<W> {
         BufWriter {
             inner: Some(inner),
@@ -165,6 +176,7 @@ fn flush_buf(&mut self) -> io::Result<()> {
     }
 
     /// Gets a reference to the underlying writer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_ref(&self) -> &W { self.inner.as_ref().unwrap() }
 
     /// Gets a mutable reference to the underlying write.
@@ -172,11 +184,13 @@ pub fn get_ref(&self) -> &W { self.inner.as_ref().unwrap() }
     /// # Warning
     ///
     /// It is inadvisable to directly read from the underlying writer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut W { self.inner.as_mut().unwrap() }
 
     /// Unwraps this `BufWriter`, returning the underlying writer.
     ///
     /// The buffer is flushed before returning the writer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
         match self.flush_buf() {
             Err(e) => Err(IntoInnerError(self, e)),
@@ -185,6 +199,7 @@ pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<W: Write> Write for BufWriter<W> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         if self.buf.len() + buf.len() > self.buf.capacity() {
@@ -224,23 +239,30 @@ impl<W> IntoInnerError<W> {
     /// Returns the error which caused the call to `into_inner` to fail.
     ///
     /// This error was returned when attempting to flush the internal buffer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn error(&self) -> &Error { &self.1 }
 
     /// Returns the underlying `BufWriter` instance which generated the error.
     ///
     /// The returned object can be used to retry a flush or re-inspect the
     /// buffer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_inner(self) -> W { self.0 }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<W> FromError<IntoInnerError<W>> for Error {
     fn from_error(iie: IntoInnerError<W>) -> Error { iie.1 }
 }
 
-impl<W> StdError for IntoInnerError<W> {
-    fn description(&self) -> &str { self.error().description() }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<W> error::Error for IntoInnerError<W> {
+    fn description(&self) -> &str {
+        error::Error::description(self.error())
+    }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<W> fmt::Display for IntoInnerError<W> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         self.error().fmt(f)
@@ -251,26 +273,41 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 /// (`0x0a`, `'\n'`) is detected.
 ///
 /// This writer will be flushed when it is dropped.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct LineWriter<W> {
     inner: BufWriter<W>,
 }
 
 impl<W: Write> LineWriter<W> {
     /// Creates a new `LineWriter`
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(inner: W) -> LineWriter<W> {
         // Lines typically aren't that long, don't use a giant buffer
-        LineWriter { inner: BufWriter::with_capacity(1024, inner) }
+        LineWriter::with_capacity(1024, inner)
+    }
+
+    /// Creates a new `LineWriter` with a specified capacity for the internal
+    /// buffer.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn with_capacity(cap: usize, inner: W) -> LineWriter<W> {
+        LineWriter { inner: BufWriter::with_capacity(cap, inner) }
     }
 
     /// Gets a reference to the underlying writer.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn get_ref(&self) -> &W { self.inner.get_ref() }
+
+    /// Gets a mutable reference to the underlying writer.
     ///
-    /// This type does not expose the ability to get a mutable reference to the
-    /// underlying reader because that could possibly corrupt the buffer.
-    pub fn get_ref<'a>(&'a self) -> &'a W { self.inner.get_ref() }
+    /// Caution must be taken when calling methods on the mutable reference
+    /// returned as extra writes could corrupt the output stream.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn get_mut(&mut self) -> &mut W { self.inner.get_mut() }
 
     /// Unwraps this `LineWriter`, returning the underlying writer.
     ///
     /// The internal buffer is flushed before returning the writer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_inner(self) -> Result<W, IntoInnerError<LineWriter<W>>> {
         self.inner.into_inner().map_err(|IntoInnerError(buf, e)| {
             IntoInnerError(LineWriter { inner: buf }, e)
@@ -278,6 +315,7 @@ pub fn into_inner(self) -> Result<W, IntoInnerError<LineWriter<W>>> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<W: Write> Write for LineWriter<W> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         match buf.rposition_elem(&b'\n') {
@@ -320,12 +358,13 @@ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
 
 /// Wraps a Stream and buffers input and output to and from it.
 ///
-/// It can be excessively inefficient to work directly with a `Stream`. For
+/// It can be excessively inefficient to work directly with a `Read+Write`. For
 /// example, every call to `read` or `write` on `TcpStream` results in a system
 /// call. A `BufStream` keeps in memory buffers of data, making large,
-/// infrequent calls to `read` and `write` on the underlying `Stream`.
+/// infrequent calls to `read` and `write` on the underlying `Read+Write`.
 ///
 /// The output half will be flushed when this stream is dropped.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct BufStream<S> {
     inner: BufReader<InternalBufWriter<S>>
 }
@@ -333,6 +372,7 @@ pub struct BufStream<S> {
 impl<S: Read + Write> BufStream<S> {
     /// Creates a new buffered stream with explicitly listed capacities for the
     /// reader/writer buffer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_capacities(reader_cap: usize, writer_cap: usize, inner: S)
                            -> BufStream<S> {
         let writer = BufWriter::with_capacity(writer_cap, inner);
@@ -343,11 +383,13 @@ pub fn with_capacities(reader_cap: usize, writer_cap: usize, inner: S)
 
     /// Creates a new buffered stream with the default reader/writer buffer
     /// capacities.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(inner: S) -> BufStream<S> {
         BufStream::with_capacities(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE, inner)
     }
 
     /// Gets a reference to the underlying stream.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_ref(&self) -> &S {
         let InternalBufWriter(ref w) = self.inner.inner;
         w.get_ref()
@@ -359,6 +401,7 @@ pub fn get_ref(&self) -> &S {
     ///
     /// It is inadvisable to read directly from or write directly to the
     /// underlying stream.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut S {
         let InternalBufWriter(ref mut w) = self.inner.inner;
         w.get_mut()
@@ -368,6 +411,7 @@ pub fn get_mut(&mut self) -> &mut S {
     ///
     /// The internal buffer is flushed before returning the stream. Any leftover
     /// data in the read buffer is lost.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_inner(self) -> Result<S, IntoInnerError<BufStream<S>>> {
         let BufReader { inner: InternalBufWriter(w), buf } = self.inner;
         w.into_inner().map_err(|IntoInnerError(w, e)| {
@@ -378,17 +422,20 @@ pub fn into_inner(self) -> Result<S, IntoInnerError<BufStream<S>>> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<S: Read + Write> BufRead for BufStream<S> {
     fn fill_buf(&mut self) -> io::Result<&[u8]> { self.inner.fill_buf() }
     fn consume(&mut self, amt: uint) { self.inner.consume(amt) }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<S: Read + Write> Read for BufStream<S> {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.inner.read(buf)
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<S: Read + Write> Write for BufStream<S> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.inner.inner.get_mut().write(buf)
index 9f3cd8c8b15deb4b68978d0df8c8343fe8486831..530c672810723a26ae7c59cfd1c6535a3e6a9105 100644 (file)
@@ -10,7 +10,7 @@
 
 use boxed::Box;
 use clone::Clone;
-use error::Error as StdError;
+use error;
 use fmt;
 use option::Option::{self, Some, None};
 use result;
@@ -22,6 +22,7 @@
 ///
 /// This typedef is generally used to avoid writing out `io::Error` directly and
 /// is otherwise a direct mapping to `std::result::Result`.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub type Result<T> = result::Result<T, Error>;
 
 /// The error type for I/O operations of the `Read`, `Write`, `Seek`, and
@@ -31,6 +32,7 @@
 /// `Error` can be created with crafted error messages and a particular value of
 /// `ErrorKind`.
 #[derive(PartialEq, Eq, Clone, Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Error {
     repr: Repr,
 }
@@ -50,6 +52,10 @@ struct Custom {
 
 /// A list specifying general categories of I/O error.
 #[derive(Copy, PartialEq, Eq, Clone, Debug)]
+#[unstable(feature = "io",
+           reason = "the interaction between OS error codes and how they map to \
+                     these names (as well as the names themselves) has not \
+                     been thoroughly thought out")]
 pub enum ErrorKind {
     /// The file was not found.
     FileNotFound,
@@ -96,6 +102,9 @@ pub enum ErrorKind {
 
 impl Error {
     /// Creates a new custom error from a specified kind/description/detail.
+    #[unstable(feature = "io", reason = "the exact makeup of an Error may
+                                         change to include `Box<Error>` for \
+                                         example")]
     pub fn new(kind: ErrorKind,
                description: &'static str,
                detail: Option<String>) -> Error {
@@ -113,16 +122,20 @@ pub fn new(kind: ErrorKind,
     /// This function reads the value of `errno` for the target platform (e.g.
     /// `GetLastError` on Windows) and will return a corresponding instance of
     /// `Error` for the error code.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn last_os_error() -> Error {
         Error::from_os_error(sys::os::errno() as i32)
     }
 
     /// Creates a new instance of an `Error` from a particular OS error code.
+    #[unstable(feature = "io",
+               reason = "unclear whether this function is necessary")]
     pub fn from_os_error(code: i32) -> Error {
         Error { repr: Repr::Os(code) }
     }
 
     /// Return the corresponding `ErrorKind` for this error.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn kind(&self) -> ErrorKind {
         match self.repr {
             Repr::Os(code) => sys::decode_error_kind(code),
@@ -131,6 +144,9 @@ pub fn kind(&self) -> ErrorKind {
     }
 
     /// Returns a short description for this error message
+    #[unstable(feature = "io")]
+    #[deprecated(since = "1.0.0", reason = "use the Error trait's description \
+                                            method instead")]
     pub fn description(&self) -> &str {
         match self.repr {
             Repr::Os(..) => "os error",
@@ -139,6 +155,8 @@ pub fn description(&self) -> &str {
     }
 
     /// Returns a detailed error message for this error (if one is available)
+    #[unstable(feature = "io")]
+    #[deprecated(since = "1.0.0", reason = "use the to_string() method instead")]
     pub fn detail(&self) -> Option<String> {
         match self.repr {
             Repr::Os(code) => Some(sys::os::error_string(code)),
@@ -147,6 +165,7 @@ pub fn detail(&self) -> Option<String> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for Error {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         match self.repr {
@@ -173,7 +192,8 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl StdError for Error {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl error::Error for Error {
     fn description(&self) -> &str {
         match self.repr {
             Repr::Os(..) => "os error",
index c968415d3efdc5670cdee690fb3cea0c6bf60032..16298240acfbed7e9968ade38f5f875c7f70e9a2 100644 (file)
@@ -27,10 +27,10 @@ impl<'a, R: Read + ?Sized> Read for &'a mut R {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         (**self).read(buf)
     }
-    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> {
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
         (**self).read_to_end(buf)
     }
-    fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> {
+    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
         (**self).read_to_string(buf)
     }
 }
@@ -53,10 +53,10 @@ fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) }
 impl<'a, B: BufRead + ?Sized> BufRead for &'a mut B {
     fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() }
     fn consume(&mut self, amt: usize) { (**self).consume(amt) }
-    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<()> {
+    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
         (**self).read_until(byte, buf)
     }
-    fn read_line(&mut self, buf: &mut String) -> io::Result<()> {
+    fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
         (**self).read_line(buf)
     }
 }
@@ -66,10 +66,10 @@ impl<R: Read + ?Sized> Read for Box<R> {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         (**self).read(buf)
     }
-    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> {
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
         (**self).read_to_end(buf)
     }
-    fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> {
+    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
         (**self).read_to_string(buf)
     }
 }
@@ -92,10 +92,10 @@ fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) }
 impl<B: BufRead + ?Sized> BufRead for Box<B> {
     fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() }
     fn consume(&mut self, amt: usize) { (**self).consume(amt) }
-    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<()> {
+    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
         (**self).read_until(byte, buf)
     }
-    fn read_line(&mut self, buf: &mut String) -> io::Result<()> {
+    fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
         (**self).read_line(buf)
     }
 }
index 9137068076b46818d30eb55a5d5cf77d5a0845a9..5500f8d6c75e6c7837cf132ddb8cd38ea0e0180e 100644 (file)
 //! > development. At this time it is still recommended to use the `old_io`
 //! > module while the details of this module shake out.
 
-#![unstable(feature = "io",
-            reason = "this new I/O module is still under active development and \
-                      APIs are subject to tweaks fairly regularly")]
+#![stable(feature = "rust1", since = "1.0.0")]
 
 use cmp;
 use unicode::str as core_str;
-use error::Error as StdError;
+use error as std_error;
 use fmt;
 use iter::Iterator;
 use marker::Sized;
@@ -111,8 +109,8 @@ unsafe fn black_box<T>(mut dummy: T) -> T {
 // 2. We're passing a raw buffer to the function `f`, and it is expected that
 //    the function only *appends* bytes to the buffer. We'll get undefined
 //    behavior if existing bytes are overwritten to have non-UTF-8 data.
-fn append_to_string<F>(buf: &mut String, f: F) -> Result<()>
-    where F: FnOnce(&mut Vec<u8>) -> Result<()>
+fn append_to_string<F>(buf: &mut String, f: F) -> Result<usize>
+    where F: FnOnce(&mut Vec<u8>) -> Result<usize>
 {
     struct Guard<'a> { s: &'a mut Vec<u8>, len: usize }
     #[unsafe_destructor]
@@ -126,7 +124,7 @@ fn drop(&mut self) {
         let mut g = Guard { len: buf.len(), s: buf.as_mut_vec() };
         let ret = f(g.s);
         if str::from_utf8(&g.s[g.len..]).is_err() {
-            ret.and_then(|()| {
+            ret.and_then(|_| {
                 Err(Error::new(ErrorKind::InvalidInput,
                                "stream did not contain valid UTF-8", None))
             })
@@ -137,14 +135,15 @@ fn drop(&mut self) {
     }
 }
 
-fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<()> {
+fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> {
+    let mut read = 0;
     loop {
         if buf.capacity() == buf.len() {
             buf.reserve(DEFAULT_BUF_SIZE);
         }
         match with_end_to_cap(buf, |b| r.read(b)) {
-            Ok(0) => return Ok(()),
-            Ok(_) => {}
+            Ok(0) => return Ok(read),
+            Ok(n) => read += n,
             Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
             Err(e) => return Err(e),
         }
@@ -159,6 +158,7 @@ fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<()> {
 /// Readers are intended to be composable with one another. Many objects
 /// throughout the I/O and related libraries take and provide types which
 /// implement the `Read` trait.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait Read {
     /// Pull some bytes from this source into the specified buffer, returning
     /// how many bytes were read.
@@ -187,6 +187,7 @@ pub trait Read {
     /// If this function encounters any form of I/O or other error, an error
     /// variant will be returned. If an error is returned then it must be
     /// guaranteed that no bytes were read.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
 
     /// Read all bytes until EOF in this source, placing them into `buf`.
@@ -198,7 +199,8 @@ pub trait Read {
     /// 2. Returns an error which is not of the kind `ErrorKind::Interrupted`.
     ///
     /// Until one of these conditions is met the function will continuously
-    /// invoke `read` to append more data to `buf`.
+    /// invoke `read` to append more data to `buf`. If successful, this function
+    /// will return the total number of bytes read.
     ///
     /// # Errors
     ///
@@ -209,19 +211,24 @@ pub trait Read {
     /// If any other read error is encountered then this function immediately
     /// returns. Any bytes which have already been read will be appended to
     /// `buf`.
-    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<()> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
         read_to_end(self, buf)
     }
 
     /// Read all bytes until EOF in this source, placing them into `buf`.
     ///
+    /// If successful, this function returns the number of bytes which were read
+    /// and appended to `buf`.
+    ///
     /// # Errors
     ///
     /// If the data in this stream is *not* valid UTF-8 then an error is
     /// returned and `buf` is unchanged.
     ///
     /// See `read_to_end` for other error semantics.
-    fn read_to_string(&mut self, buf: &mut String) -> Result<()> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
         // Note that we do *not* call `.read_to_end()` here. We are passing
         // `&mut Vec<u8>` (the raw contents of `buf`) into the `read_to_end`
         // method to fill it up. An arbitrary implementation could overwrite the
@@ -233,18 +240,13 @@ fn read_to_string(&mut self, buf: &mut String) -> Result<()> {
         // know is guaranteed to only read data into the end of the buffer.
         append_to_string(buf, |b| read_to_end(self, b))
     }
-}
 
-/// Extension methods for all instances of `Read`, typically imported through
-/// `std::io::prelude::*`.
-#[unstable(feature = "io", reason = "may merge into the Read trait")]
-pub trait ReadExt: Read + Sized {
     /// Create a "by reference" adaptor for this instance of `Read`.
     ///
     /// The returned adaptor also implements `Read` and will simply borrow this
     /// current reader.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn by_ref(&mut self) -> &mut Self { self }
+    fn by_ref(&mut self) -> &mut Self where Self: Sized { self }
 
     /// Transform this `Read` instance to an `Iterator` over its bytes.
     ///
@@ -253,7 +255,7 @@ fn by_ref(&mut self) -> &mut Self { self }
     /// `Err` otherwise for I/O errors. EOF is mapped to returning `None` from
     /// this iterator.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn bytes(self) -> Bytes<Self> {
+    fn bytes(self) -> Bytes<Self> where Self: Sized {
         Bytes { inner: self }
     }
 
@@ -270,7 +272,7 @@ fn bytes(self) -> Bytes<Self> {
     #[unstable(feature = "io", reason = "the semantics of a partial read/write \
                                          of where errors happen is currently \
                                          unclear and may change")]
-    fn chars(self) -> Chars<Self> {
+    fn chars(self) -> Chars<Self> where Self: Sized {
         Chars { inner: self }
     }
 
@@ -280,7 +282,7 @@ fn chars(self) -> Chars<Self> {
     /// until EOF is encountered. Afterwards the output is equivalent to the
     /// output of `next`.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn chain<R: Read>(self, next: R) -> Chain<Self, R> {
+    fn chain<R: Read>(self, next: R) -> Chain<Self, R> where Self: Sized {
         Chain { first: self, second: next, done_first: false }
     }
 
@@ -291,7 +293,7 @@ fn chain<R: Read>(self, next: R) -> Chain<Self, R> {
     /// read errors will not count towards the number of bytes read and future
     /// calls to `read` may succeed.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn take(self, limit: u64) -> Take<Self> {
+    fn take(self, limit: u64) -> Take<Self> where Self: Sized {
         Take { inner: self, limit: limit }
     }
 
@@ -304,13 +306,11 @@ fn take(self, limit: u64) -> Take<Self> {
     #[unstable(feature = "io", reason = "the semantics of a partial read/write \
                                          of where errors happen is currently \
                                          unclear and may change")]
-    fn tee<W: Write>(self, out: W) -> Tee<Self, W> {
+    fn tee<W: Write>(self, out: W) -> Tee<Self, W> where Self: Sized {
         Tee { reader: self, writer: out }
     }
 }
 
-impl<T: Read> ReadExt for T {}
-
 /// A trait for objects which are byte-oriented sinks.
 ///
 /// The `write` method will attempt to write some data into the object,
@@ -322,6 +322,7 @@ impl<T: Read> ReadExt for T {}
 /// Writers are intended to be composable with one another. Many objects
 /// throughout the I/O and related libraries take and provide types which
 /// implement the `Write` trait.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait Write {
     /// Write a buffer into this object, returning how many bytes were written.
     ///
@@ -347,6 +348,7 @@ pub trait Write {
     ///
     /// It is **not** considered an error if the entire buffer could not be
     /// written to this writer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn write(&mut self, buf: &[u8]) -> Result<usize>;
 
     /// Flush this output stream, ensuring that all intermediately buffered
@@ -356,6 +358,7 @@ pub trait Write {
     ///
     /// It is considered an error if not all bytes could be written due to
     /// I/O errors or EOF being reached.
+    #[unstable(feature = "io", reason = "waiting for RFC 950")]
     fn flush(&mut self) -> Result<()>;
 
     /// Attempts to write an entire buffer into this write.
@@ -368,6 +371,7 @@ pub trait Write {
     /// # Errors
     ///
     /// This function will return the first error that `write` returns.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
         while buf.len() > 0 {
             match self.write(buf) {
@@ -396,6 +400,7 @@ fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
     /// # Errors
     ///
     /// This function will return any I/O error reported while formatting.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn write_fmt(&mut self, fmt: fmt::Arguments) -> Result<()> {
         // Create a shim which translates a Write to a fmt::Write and saves
         // off I/O errors. instead of discarding them
@@ -422,18 +427,13 @@ fn write_str(&mut self, s: &str) -> fmt::Result {
             Err(..) => output.error
         }
     }
-}
 
-/// Extension methods for all instances of `Write`, typically imported through
-/// `std::io::prelude::*`.
-#[unstable(feature = "io", reason = "may merge into the Read trait")]
-pub trait WriteExt: Write + Sized {
     /// Create a "by reference" adaptor for this instance of `Write`.
     ///
     /// The returned adaptor also implements `Write` and will simply borrow this
     /// current writer.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn by_ref(&mut self) -> &mut Self { self }
+    fn by_ref(&mut self) -> &mut Self where Self: Sized { self }
 
     /// Creates a new writer which will write all data to both this writer and
     /// another writer.
@@ -446,19 +446,21 @@ fn by_ref(&mut self) -> &mut Self { self }
     #[unstable(feature = "io", reason = "the semantics of a partial read/write \
                                          of where errors happen is currently \
                                          unclear and may change")]
-    fn broadcast<W: Write>(self, other: W) -> Broadcast<Self, W> {
+    fn broadcast<W: Write>(self, other: W) -> Broadcast<Self, W>
+        where Self: Sized
+    {
         Broadcast { first: self, second: other }
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Write> WriteExt for T {}
-
 /// An object implementing `Seek` internally has some form of cursor which can
 /// be moved within a stream of bytes.
 ///
 /// The stream typically has a fixed size, allowing seeking relative to either
 /// end or the current offset.
+#[unstable(feature = "io", reason = "the central `seek` method may be split \
+                                     into multiple methods instead of taking \
+                                     an enum as an argument")]
 pub trait Seek {
     /// Seek to an offset, in bytes, in a stream
     ///
@@ -479,6 +481,7 @@ pub trait Seek {
 
 /// Enumeration of possible methods to seek within an I/O object.
 #[derive(Copy, PartialEq, Eq, Clone, Debug)]
+#[unstable(feature = "io", reason = "awaiting the stability of Seek")]
 pub enum SeekFrom {
     /// Set the offset to the provided number of bytes.
     Start(u64),
@@ -499,7 +502,8 @@ pub enum SeekFrom {
 }
 
 fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
-                                   -> Result<()> {
+                                   -> Result<usize> {
+    let mut read = 0;
     loop {
         let (done, used) = {
             let available = match r.fill_buf() {
@@ -519,8 +523,9 @@ fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
             }
         };
         r.consume(used);
+        read += used;
         if done || used == 0 {
-            return Ok(());
+            return Ok(read);
         }
     }
 }
@@ -530,6 +535,7 @@ fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
 ///
 /// This type extends the `Read` trait with a few methods that are not
 /// possible to reasonably implement with purely a read interface.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait BufRead: Read {
     /// Fills the internal buffer of this object, returning the buffer contents.
     ///
@@ -546,10 +552,16 @@ pub trait BufRead: Read {
     ///
     /// This function will return an I/O error if the underlying reader was
     /// read, but returned an error.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn fill_buf(&mut self) -> Result<&[u8]>;
 
     /// Tells this buffer that `amt` bytes have been consumed from the buffer,
     /// so they should no longer be returned in calls to `read`.
+    ///
+    /// This function does not perform any I/O, it simply informs this object
+    /// that some amount of its buffer, returned from `fill_buf`, has been
+    /// consumed and should no longer be returned.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn consume(&mut self, amt: usize);
 
     /// Read all bytes until the delimiter `byte` is reached.
@@ -560,7 +572,8 @@ pub trait BufRead: Read {
     /// `buf`.
     ///
     /// If this buffered reader is currently at EOF, then this function will not
-    /// place any more bytes into `buf` and will return `Ok(())`.
+    /// place any more bytes into `buf` and will return `Ok(n)` where `n` is the
+    /// number of bytes which were read.
     ///
     /// # Errors
     ///
@@ -569,7 +582,8 @@ pub trait BufRead: Read {
     ///
     /// If an I/O error is encountered then all bytes read so far will be
     /// present in `buf` and its length will have been adjusted appropriately.
-    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<()> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {
         read_until(self, byte, buf)
     }
 
@@ -581,7 +595,8 @@ fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<()> {
     /// found) will be appended to `buf`.
     ///
     /// If this reader is currently at EOF then this function will not modify
-    /// `buf` and will return `Ok(())`.
+    /// `buf` and will return `Ok(n)` where `n` is the number of bytes which
+    /// were read.
     ///
     /// # Errors
     ///
@@ -589,17 +604,14 @@ fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<()> {
     /// return an error if the read bytes are not valid UTF-8. If an I/O error
     /// is encountered then `buf` may contain some bytes already read in the
     /// event that all data read so far was valid UTF-8.
-    fn read_line(&mut self, buf: &mut String) -> Result<()> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn read_line(&mut self, buf: &mut String) -> Result<usize> {
         // Note that we are not calling the `.read_until` method here, but
         // rather our hardcoded implementation. For more details as to why, see
         // the comments in `read_to_end`.
         append_to_string(buf, |b| read_until(self, b'\n', b))
     }
-}
 
-/// Extension methods for all instances of `BufRead`, typically imported through
-/// `std::io::prelude::*`.
-pub trait BufReadExt: BufRead + Sized {
     /// Returns an iterator over the contents of this reader split on the byte
     /// `byte`.
     ///
@@ -611,7 +623,7 @@ pub trait BufReadExt: BufRead + Sized {
     /// yielded an error.
     #[unstable(feature = "io", reason = "may be renamed to not conflict with \
                                          SliceExt::split")]
-    fn split(self, byte: u8) -> Split<Self> {
+    fn split(self, byte: u8) -> Split<Self> where Self: Sized {
         Split { buf: self, delim: byte }
     }
 
@@ -624,22 +636,21 @@ fn split(self, byte: u8) -> Split<Self> {
     /// This function will yield errors whenever `read_string` would have also
     /// yielded an error.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn lines(self) -> Lines<Self> {
+    fn lines(self) -> Lines<Self> where Self: Sized {
         Lines { buf: self }
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: BufRead> BufReadExt for T {}
-
 /// A `Write` adaptor which will write data to multiple locations.
 ///
 /// For more information, see `WriteExt::broadcast`.
+#[unstable(feature = "io", reason = "awaiting stability of WriteExt::broadcast")]
 pub struct Broadcast<T, U> {
     first: T,
     second: U,
 }
 
+#[unstable(feature = "io", reason = "awaiting stability of WriteExt::broadcast")]
 impl<T: Write, U: Write> Write for Broadcast<T, U> {
     fn write(&mut self, data: &[u8]) -> Result<usize> {
         let n = try!(self.first.write(data));
@@ -732,11 +743,13 @@ fn consume(&mut self, amt: usize) {
 /// An adaptor which will emit all read data to a specified writer as well.
 ///
 /// For more information see `ReadExt::tee`
+#[unstable(feature = "io", reason = "awaiting stability of ReadExt::tee")]
 pub struct Tee<R, W> {
     reader: R,
     writer: W,
 }
 
+#[unstable(feature = "io", reason = "awaiting stability of ReadExt::tee")]
 impl<R: Read, W: Write> Read for Tee<R, W> {
     fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
         let n = try!(self.reader.read(buf));
@@ -771,6 +784,7 @@ fn next(&mut self) -> Option<Result<u8>> {
 /// A bridge from implementations of `Read` to an `Iterator` of `char`.
 ///
 /// See `ReadExt::chars` for more information.
+#[unstable(feature = "io", reason = "awaiting stability of ReadExt::chars")]
 pub struct Chars<R> {
     inner: R,
 }
@@ -778,6 +792,7 @@ pub struct Chars<R> {
 /// An enumeration of possible errors that can be generated from the `Chars`
 /// adapter.
 #[derive(PartialEq, Clone, Debug)]
+#[unstable(feature = "io", reason = "awaiting stability of ReadExt::chars")]
 pub enum CharsError {
     /// Variant representing that the underlying stream was read successfully
     /// but it did not contain valid utf8 data.
@@ -787,6 +802,7 @@ pub enum CharsError {
     Other(Error),
 }
 
+#[unstable(feature = "io", reason = "awaiting stability of ReadExt::chars")]
 impl<R: Read> Iterator for Chars<R> {
     type Item = result::Result<char, CharsError>;
 
@@ -818,14 +834,15 @@ fn next(&mut self) -> Option<result::Result<char, CharsError>> {
     }
 }
 
-impl StdError for CharsError {
+#[unstable(feature = "io", reason = "awaiting stability of ReadExt::chars")]
+impl std_error::Error for CharsError {
     fn description(&self) -> &str {
         match *self {
             CharsError::NotUtf8 => "invalid utf8 encoding",
-            CharsError::Other(ref e) => e.description(),
+            CharsError::Other(ref e) => std_error::Error::description(e),
         }
     }
-    fn cause(&self) -> Option<&StdError> {
+    fn cause(&self) -> Option<&std_error::Error> {
         match *self {
             CharsError::NotUtf8 => None,
             CharsError::Other(ref e) => e.cause(),
@@ -833,6 +850,7 @@ fn cause(&self) -> Option<&StdError> {
     }
 }
 
+#[unstable(feature = "io", reason = "awaiting stability of ReadExt::chars")]
 impl fmt::Display for CharsError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
@@ -848,19 +866,21 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 /// particular byte.
 ///
 /// See `BufReadExt::split` for more information.
+#[unstable(feature = "io", reason = "awaiting stability of BufReadExt::split")]
 pub struct Split<B> {
     buf: B,
     delim: u8,
 }
 
+#[unstable(feature = "io", reason = "awaiting stability of BufReadExt::split")]
 impl<B: BufRead> Iterator for Split<B> {
     type Item = Result<Vec<u8>>;
 
     fn next(&mut self) -> Option<Result<Vec<u8>>> {
         let mut buf = Vec::new();
         match self.buf.read_until(self.delim, &mut buf) {
-            Ok(()) if buf.len() == 0 => None,
-            Ok(()) => {
+            Ok(0) => None,
+            Ok(_n) => {
                 if buf[buf.len() - 1] == self.delim {
                     buf.pop();
                 }
@@ -887,8 +907,8 @@ impl<B: BufRead> Iterator for Lines<B> {
     fn next(&mut self) -> Option<Result<String>> {
         let mut buf = String::new();
         match self.buf.read_line(&mut buf) {
-            Ok(()) if buf.len() == 0 => None,
-            Ok(()) => {
+            Ok(0) => None,
+            Ok(_n) => {
                 if buf.ends_with("\n") {
                     buf.pop();
                 }
index 637b1950985fd79f2e9e5c278192aead8c048157..6bf0ebd1a59e9c8b0a744e7be449f6f83c2d18ef 100644 (file)
@@ -21,7 +21,9 @@
 //! `Write`, `ReadExt`, and `WriteExt`. Structures and functions are not
 //! contained in this module.
 
-pub use super::{Read, ReadExt, Write, WriteExt, BufRead, BufReadExt};
+#![stable(feature = "rust1", since = "1.0.0")]
+
+pub use super::{Read, Write, BufRead};
 pub use fs::PathExt;
 
 // FIXME: pub use as `Seek` when the name isn't in the actual prelude any more
index 4027f741654b66bbbf57c9644f06e66bb7866b30..c8625a2765d1ace9ebfbc4190de4e8843704b8e5 100644 (file)
@@ -86,6 +86,7 @@ fn flush(&mut self) -> io::Result<()> { Ok(()) }
 ///
 /// This handle implements the `Read` trait, but beware that concurrent reads
 /// of `Stdin` must be executed with care.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stdin {
     inner: Arc<Mutex<BufReader<StdinRaw>>>,
 }
@@ -94,6 +95,7 @@ pub struct Stdin {
 ///
 /// This handle implements both the `Read` and `BufRead` traits and is
 /// constructed via the `lock` method on `Stdin`.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct StdinLock<'a> {
     inner: MutexGuard<'a, BufReader<StdinRaw>>,
 }
@@ -110,6 +112,7 @@ pub struct StdinLock<'a> {
 ///
 /// To avoid locking and buffering altogether, it is recommended to use the
 /// `stdin_raw` constructor.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub fn stdin() -> Stdin {
     static INSTANCE: Lazy<Mutex<BufReader<StdinRaw>>> = lazy_init!(stdin_init);
     return Stdin {
@@ -136,30 +139,41 @@ impl Stdin {
     /// The lock is released when the returned lock goes out of scope. The
     /// returned guard also implements the `Read` and `BufRead` traits for
     /// accessing the underlying data.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> StdinLock {
         StdinLock { inner: self.inner.lock().unwrap() }
     }
+
+    /// Locks this handle and reads a line of input into the specified buffer.
+    ///
+    /// For detailed semantics of this method, see the documentation on
+    /// `BufRead::read_line`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
+        self.lock().read_line(buf)
+    }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Read for Stdin {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.lock().read(buf)
     }
-
-    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> {
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
         self.lock().read_to_end(buf)
     }
-
-    fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> {
+    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
         self.lock().read_to_string(buf)
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Read for StdinLock<'a> {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.inner.read(buf)
     }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> BufRead for StdinLock<'a> {
     fn fill_buf(&mut self) -> io::Result<&[u8]> { self.inner.fill_buf() }
     fn consume(&mut self, n: usize) { self.inner.consume(n) }
@@ -186,6 +200,7 @@ fn consume(&mut self, n: usize) { self.inner.consume(n) }
 /// Each handle shares a global buffer of data to be written to the standard
 /// output stream. Access is also synchronized via a lock and explicit control
 /// over locking is available via the `lock` method.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stdout {
     // FIXME: this should be LineWriter or BufWriter depending on the state of
     //        stdout (tty or not). Note that if this is not line buffered it
@@ -197,6 +212,7 @@ pub struct Stdout {
 ///
 /// This handle implements the `Write` trait and is constructed via the `lock`
 /// method on `Stdout`.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct StdoutLock<'a> {
     inner: MutexGuard<'a, LineWriter<StdoutRaw>>,
 }
@@ -211,6 +227,7 @@ pub struct StdoutLock<'a> {
 ///
 /// To avoid locking and buffering altogether, it is recommended to use the
 /// `stdout_raw` constructor.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub fn stdout() -> Stdout {
     static INSTANCE: Lazy<Mutex<LineWriter<StdoutRaw>>> = lazy_init!(stdout_init);
     return Stdout {
@@ -228,11 +245,13 @@ impl Stdout {
     ///
     /// The lock is released when the returned lock goes out of scope. The
     /// returned guard also implements the `Write` trait for writing data.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> StdoutLock {
         StdoutLock { inner: self.inner.lock().unwrap() }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Write for Stdout {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.lock().write(buf)
@@ -247,6 +266,7 @@ fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
         self.lock().write_fmt(fmt)
     }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Write for StdoutLock<'a> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.inner.write(&buf[..cmp::min(buf.len(), OUT_MAX)])
@@ -257,6 +277,7 @@ fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
 /// A handle to the standard error stream of a process.
 ///
 /// For more information, see `stderr`
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stderr {
     inner: Arc<Mutex<StderrRaw>>,
 }
@@ -265,6 +286,7 @@ pub struct Stderr {
 ///
 /// This handle implements the `Write` trait and is constructed via the `lock`
 /// method on `Stderr`.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct StderrLock<'a> {
     inner: MutexGuard<'a, StderrRaw>,
 }
@@ -278,6 +300,7 @@ pub struct StderrLock<'a> {
 ///
 /// To avoid locking altogether, it is recommended to use the `stderr_raw`
 /// constructor.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub fn stderr() -> Stderr {
     static INSTANCE: Lazy<Mutex<StderrRaw>> = lazy_init!(stderr_init);
     return Stderr {
@@ -295,11 +318,13 @@ impl Stderr {
     ///
     /// The lock is released when the returned lock goes out of scope. The
     /// returned guard also implements the `Write` trait for writing data.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> StderrLock {
         StderrLock { inner: self.inner.lock().unwrap() }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Write for Stderr {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.lock().write(buf)
@@ -314,6 +339,7 @@ fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
         self.lock().write_fmt(fmt)
     }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Write for StderrLock<'a> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.inner.write(&buf[..cmp::min(buf.len(), OUT_MAX)])
index f71698fa72586db925a904eaa4f805c21c1ad156..9d438978f4211e67f5dd787689220f9e7ffea5d4 100644 (file)
 #![deny(unused_must_use)]
 #![allow(deprecated)] // seriously this is all deprecated
 #![allow(unused_imports)]
+#![deprecated(since = "1.0.0",
+              reasons = "APIs have been replaced with new I/O modules such as \
+                         std::{io, fs, net, process}")]
 
 pub use self::SeekStyle::*;
 pub use self::FileMode::*;
index 5c5f9f75fd9dbda818ec949e845869be9e19ee0e..dcf7a37b7a650701c50c8e296630992f11260731 100644 (file)
 use fmt;
 use io;
 use marker::PhantomData;
-use old_io::stdio;
 use rt::{self, unwind};
 use sync::{Mutex, Condvar, Arc};
 use thunk::Thunk;
@@ -165,10 +164,6 @@ pub struct Builder {
     name: Option<String>,
     // The size of the stack for the spawned thread
     stack_size: Option<usize>,
-    // Thread-local stdout
-    stdout: Option<Box<Writer + Send + 'static>>,
-    // Thread-local stderr
-    stderr: Option<Box<Writer + Send + 'static>>,
 }
 
 impl Builder {
@@ -179,8 +174,6 @@ pub fn new() -> Builder {
         Builder {
             name: None,
             stack_size: None,
-            stdout: None,
-            stderr: None,
         }
     }
 
@@ -202,16 +195,22 @@ pub fn stack_size(mut self, size: usize) -> Builder {
     /// Redirect thread-local stdout.
     #[unstable(feature = "std_misc",
                reason = "Will likely go away after proc removal")]
-    pub fn stdout(mut self, stdout: Box<Writer + Send + 'static>) -> Builder {
-        self.stdout = Some(stdout);
+    #[deprecated(since = "1.0.0",
+                 reason = "the old I/O module is deprecated and this function \
+                           will be removed with no replacement")]
+    #[allow(deprecated)]
+    pub fn stdout(self, _stdout: Box<Writer + Send + 'static>) -> Builder {
         self
     }
 
     /// Redirect thread-local stderr.
     #[unstable(feature = "std_misc",
                reason = "Will likely go away after proc removal")]
-    pub fn stderr(mut self, stderr: Box<Writer + Send + 'static>) -> Builder {
-        self.stderr = Some(stderr);
+    #[deprecated(since = "1.0.0",
+                 reason = "the old I/O module is deprecated and this function \
+                           will be removed with no replacement")]
+    #[allow(deprecated)]
+    pub fn stderr(self, _stderr: Box<Writer + Send + 'static>) -> Builder {
         self
     }
 
@@ -259,7 +258,7 @@ pub fn scoped<'a, T, F>(self, f: F) -> io::Result<JoinGuard<'a, T>> where
     }
 
     fn spawn_inner<T: Send>(self, f: Thunk<(), T>) -> io::Result<JoinInner<T>> {
-        let Builder { name, stack_size, stdout, stderr } = self;
+        let Builder { name, stack_size } = self;
 
         let stack_size = stack_size.unwrap_or(rt::min_stack());
 
@@ -290,16 +289,6 @@ fn spawn_inner<T: Send>(self, f: Thunk<(), T>) -> io::Result<JoinInner<T>> {
             }
 
             let mut output = None;
-            let f: Thunk<(), T> = if stdout.is_some() || stderr.is_some() {
-                Thunk::new(move || {
-                    let _ = stdout.map(stdio::set_stdout);
-                    let _ = stderr.map(stdio::set_stderr);
-                    f.invoke(())
-                })
-            } else {
-                f
-            };
-
             let try_result = {
                 let ptr = &mut output;