diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-03-03 14:49:03 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-03-04 17:04:22 -0800 |
| commit | 0dfa9978cc57efc8eb51485fc3a333eafd1aa392 (patch) | |
| tree | 65f908ddcdc4b017d04d144c3ebc860aefc896dc /src/libstd/io | |
| parent | 129173f1980e9ac03f7ef0fc0193c41235d07649 (diff) | |
| download | rust-0dfa9978cc57efc8eb51485fc3a333eafd1aa392.tar.gz rust-0dfa9978cc57efc8eb51485fc3a333eafd1aa392.zip | |
std: Stabilize portions of the `io` module
The new `io` module has had some time to bake and this commit stabilizes some of
the utilities associated with it. This commit also deprecates a number of
`std::old_io::util` functions and structures.
These items are now `#[stable]`
* `Cursor`
* `Cursor::{new, into_inner, get_ref, get_mut, position, set_position}`
* Implementations of I/O traits for `Cursor<T>`
* Delegating implementations of I/O traits for references and `Box` pointers
* Implementations of I/O traits for primitives like slices and `Vec<T>`
* `ReadExt::bytes`
* `Bytes` (and impls)
* `ReadExt::chain`
* `Chain` (and impls)
* `ReadExt::take` (and impls)
* `BufReadExt::lines`
* `Lines` (and impls)
* `io::copy`
* `io::{empty, Empty}` (and impls)
* `io::{sink, Sink}` (and impls)
* `io::{repeat, Repeat}` (and impls)
These items remain `#[unstable]`
* Core I/O traits. These may want a little bit more time to bake along with the
commonly used methods like `read_to_end`.
* `BufReadExt::split` - this function may be renamed to not conflict with
`SliceExt::split`.
* `Error` - there are a number of questions about its representation,
`ErrorKind`, and usability.
These items are now `#[deprecated]` in `old_io`
* `LimitReader` - use `take` instead
* `NullWriter` - use `io::sink` instead
* `ZeroReader` - use `io::repeat` instead
* `NullReader` - use `io::empty` instead
* `MultiWriter` - use `broadcast` instead
* `ChainedReader` - use `chain` instead
* `TeeReader` - use `tee` instead
* `copy` - use `io::copy` instead
[breaking-change]
Diffstat (limited to 'src/libstd/io')
| -rw-r--r-- | src/libstd/io/cursor.rs | 20 | ||||
| -rw-r--r-- | src/libstd/io/impls.rs | 64 | ||||
| -rw-r--r-- | src/libstd/io/mod.rs | 32 | ||||
| -rw-r--r-- | src/libstd/io/util.rs | 17 |
4 files changed, 115 insertions, 18 deletions
diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs index b1779587528..78f9222bde7 100644 --- a/src/libstd/io/cursor.rs +++ b/src/libstd/io/cursor.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![allow(missing_copy_implementations)] - use prelude::v1::*; use io::prelude::*; @@ -32,6 +30,7 @@ use slice; /// Implementations of the I/O traits for `Cursor<T>` are not currently generic /// over `T` itself. Instead, specific implementations are provided for various /// in-memory buffer types like `Vec<u8>` and `&[u8]`. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Cursor<T> { inner: T, pos: u64, @@ -39,26 +38,32 @@ pub struct Cursor<T> { impl<T> Cursor<T> { /// Create a new cursor wrapping the provided underlying I/O object. + #[stable(feature = "rust1", since = "1.0.0")] pub fn new(inner: T) -> Cursor<T> { Cursor { pos: 0, inner: inner } } /// Consume this cursor, returning the underlying value. + #[stable(feature = "rust1", since = "1.0.0")] pub fn into_inner(self) -> T { self.inner } /// Get a reference to the underlying value in this cursor. + #[stable(feature = "rust1", since = "1.0.0")] pub fn get_ref(&self) -> &T { &self.inner } /// Get a mutable reference to the underlying value in this cursor. /// /// Care should be taken to avoid modifying the internal I/O state of the /// underlying value as it may corrupt this cursor's position. + #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self) -> &mut T { &mut self.inner } /// Returns the current value of this cursor + #[stable(feature = "rust1", since = "1.0.0")] pub fn position(&self) -> u64 { self.pos } /// Sets the value of this cursor + #[stable(feature = "rust1", since = "1.0.0")] pub fn set_position(&mut self, pos: u64) { self.pos = pos; } } @@ -83,8 +88,11 @@ macro_rules! seek { } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> io::Seek for Cursor<&'a [u8]> { seek!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> io::Seek for Cursor<&'a mut [u8]> { seek!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl io::Seek for Cursor<Vec<u8>> { seek!(); } macro_rules! read { @@ -97,8 +105,11 @@ macro_rules! read { } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Read for Cursor<&'a [u8]> { read!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Read for Cursor<&'a mut [u8]> { read!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for Cursor<Vec<u8>> { read!(); } macro_rules! buffer { @@ -111,10 +122,14 @@ macro_rules! buffer { } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> BufRead for Cursor<&'a [u8]> { buffer!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> BufRead for Cursor<&'a mut [u8]> { buffer!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> BufRead for Cursor<Vec<u8>> { buffer!(); } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Write for Cursor<&'a mut [u8]> { fn write(&mut self, data: &[u8]) -> io::Result<usize> { let pos = cmp::min(self.pos, self.inner.len() as u64); @@ -125,6 +140,7 @@ impl<'a> Write for Cursor<&'a mut [u8]> { fn flush(&mut self) -> io::Result<()> { Ok(()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Write for Cursor<Vec<u8>> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { // Make sure the internal buffer is as least as big as where we diff --git a/src/libstd/io/impls.rs b/src/libstd/io/impls.rs index 82b69ddebff..c968415d3ef 100644 --- a/src/libstd/io/impls.rs +++ b/src/libstd/io/impls.rs @@ -22,57 +22,88 @@ use vec::Vec; // ============================================================================= // Forwarding implementations +#[stable(feature = "rust1", since = "1.0.0")] 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<()> { (**self).read_to_end(buf) } - + 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<()> { + (**self).read_to_end(buf) + } fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> { (**self).read_to_string(buf) } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, W: Write + ?Sized> Write for &'a mut W { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) } - - fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { (**self).write_all(buf) } - - fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> { (**self).write_fmt(fmt) } - fn flush(&mut self) -> io::Result<()> { (**self).flush() } + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + (**self).write_all(buf) + } + fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> { + (**self).write_fmt(fmt) + } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, S: Seek + ?Sized> Seek for &'a mut S { fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) } } +#[stable(feature = "rust1", since = "1.0.0")] 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<()> { (**self).read_until(byte, buf) } - - fn read_line(&mut self, buf: &mut String) -> io::Result<()> { (**self).read_line(buf) } + fn read_line(&mut self, buf: &mut String) -> io::Result<()> { + (**self).read_line(buf) + } } +#[stable(feature = "rust1", since = "1.0.0")] impl<R: Read + ?Sized> Read for Box<R> { - fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { (**self).read(buf) } + 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<()> { + (**self).read_to_end(buf) + } + fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> { + (**self).read_to_string(buf) + } } +#[stable(feature = "rust1", since = "1.0.0")] impl<W: Write + ?Sized> Write for Box<W> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) } fn flush(&mut self) -> io::Result<()> { (**self).flush() } + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + (**self).write_all(buf) + } + fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> { + (**self).write_fmt(fmt) + } } +#[stable(feature = "rust1", since = "1.0.0")] impl<S: Seek + ?Sized> Seek for Box<S> { fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) } } +#[stable(feature = "rust1", since = "1.0.0")] 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<()> { + (**self).read_until(byte, buf) + } + fn read_line(&mut self, buf: &mut String) -> io::Result<()> { + (**self).read_line(buf) + } } // ============================================================================= // In-memory buffer implementations +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Read for &'a [u8] { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { let amt = cmp::min(buf.len(), self.len()); @@ -83,11 +114,13 @@ impl<'a> Read for &'a [u8] { } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> BufRead for &'a [u8] { fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(*self) } fn consume(&mut self, amt: usize) { *self = &self[amt..]; } } +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Write for &'a mut [u8] { fn write(&mut self, data: &[u8]) -> io::Result<usize> { let amt = cmp::min(data.len(), self.len()); @@ -108,6 +141,7 @@ impl<'a> Write for &'a mut [u8] { fn flush(&mut self) -> io::Result<()> { Ok(()) } } +#[stable(feature = "rust1", since = "1.0.0")] impl Write for Vec<u8> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.push_all(buf); @@ -115,7 +149,7 @@ impl Write for Vec<u8> { } fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - try!(self.write(buf)); + self.push_all(buf); Ok(()) } diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 5510c0203e6..a91ab57c7e9 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -237,11 +237,13 @@ pub trait Read { /// 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 } /// Transform this `Read` instance to an `Iterator` over its bytes. @@ -250,6 +252,7 @@ pub trait ReadExt: Read + Sized { /// R::Err>`. The yielded item is `Ok` if a byte was successfully read and /// `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> { Bytes { inner: self } } @@ -264,6 +267,9 @@ pub trait ReadExt: Read + Sized { /// /// Currently this adaptor will discard intermediate data read, and should /// be avoided if this is not desired. + #[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> { Chars { inner: self } } @@ -273,6 +279,7 @@ pub trait ReadExt: Read + Sized { /// The returned `Read` instance will first read all bytes from this object /// 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> { Chain { first: self, second: next, done_first: false } } @@ -283,6 +290,7 @@ pub trait ReadExt: Read + Sized { /// `limit` bytes, after which it will always return EOF (`Ok(0)`). Any /// 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> { Take { inner: self, limit: limit } } @@ -293,6 +301,9 @@ pub trait ReadExt: Read + Sized { /// Whenever the returned `Read` instance is read it will write the read /// data to `out`. The current semantics of this implementation imply that /// a `write` error will not report how much data was initially read. + #[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> { Tee { reader: self, writer: out } } @@ -415,11 +426,13 @@ pub trait Write { /// 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 } /// Creates a new writer which will write all data to both this writer and @@ -430,11 +443,15 @@ pub trait WriteExt: Write + Sized { /// implementation do not precisely track where errors happen. For example /// an error on the second call to `write` will not report that the first /// call to `write` succeeded. + #[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> { 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 @@ -592,6 +609,8 @@ pub trait BufReadExt: BufRead + Sized { /// /// This function will yield errors whenever `read_until` would have also /// yielded an error. + #[unstable(feature = "io", reason = "may be renamed to not conflict with \ + SliceExt::split")] fn split(self, byte: u8) -> Split<Self> { Split { buf: self, delim: byte } } @@ -604,11 +623,13 @@ pub trait BufReadExt: BufRead + Sized { /// /// 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> { 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. @@ -635,12 +656,14 @@ impl<T: Write, U: Write> Write for Broadcast<T, U> { /// Adaptor to chain together two instances of `Read`. /// /// For more information, see `ReadExt::chain`. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Chain<T, U> { first: T, second: U, done_first: bool, } +#[stable(feature = "rust1", since = "1.0.0")] impl<T: Read, U: Read> Read for Chain<T, U> { fn read(&mut self, buf: &mut [u8]) -> Result<usize> { if !self.done_first { @@ -656,11 +679,13 @@ impl<T: Read, U: Read> Read for Chain<T, U> { /// Reader adaptor which limits the bytes read from an underlying reader. /// /// For more information, see `ReadExt::take`. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Take<T> { inner: T, limit: u64, } +#[stable(feature = "rust1", since = "1.0.0")] impl<T> Take<T> { /// Returns the number of bytes that can be read before this instance will /// return EOF. @@ -669,9 +694,11 @@ impl<T> Take<T> { /// /// This instance may reach EOF after reading fewer bytes than indicated by /// this method if the underlying `Read` instance reaches EOF. + #[stable(feature = "rust1", since = "1.0.0")] pub fn limit(&self) -> u64 { self.limit } } +#[stable(feature = "rust1", since = "1.0.0")] impl<T: Read> Read for Take<T> { fn read(&mut self, buf: &mut [u8]) -> Result<usize> { // Don't call into inner reader at all at EOF because it may still block @@ -686,6 +713,7 @@ impl<T: Read> Read for Take<T> { } } +#[stable(feature = "rust1", since = "1.0.0")] impl<T: BufRead> BufRead for Take<T> { fn fill_buf(&mut self) -> Result<&[u8]> { let buf = try!(self.inner.fill_buf()); @@ -721,10 +749,12 @@ impl<R: Read, W: Write> Read for Tee<R, W> { /// A bridge from implementations of `Read` to an `Iterator` of `u8`. /// /// See `ReadExt::bytes` for more information. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Bytes<R> { inner: R, } +#[stable(feature = "rust1", since = "1.0.0")] impl<R: Read> Iterator for Bytes<R> { type Item = Result<u8>; @@ -845,10 +875,12 @@ impl<B: BufRead> Iterator for Split<B> { /// byte. /// /// See `BufReadExt::lines` for more information. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Lines<B> { buf: B, } +#[stable(feature = "rust1", since = "1.0.0")] impl<B: BufRead> Iterator for Lines<B> { type Item = Result<String>; diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs index 3d342137c62..20426025257 100644 --- a/src/libstd/io/util.rs +++ b/src/libstd/io/util.rs @@ -12,7 +12,7 @@ use prelude::v1::*; -use io::{self, Read, Write, ErrorKind}; +use io::{self, Read, Write, ErrorKind, BufRead}; /// Copies the entire contents of a reader into a writer. /// @@ -27,6 +27,7 @@ use io::{self, Read, Write, ErrorKind}; /// This function will return an error immediately if any call to `read` or /// `write` returns an error. All instances of `ErrorKind::Interrupted` are /// handled by this function and the underlying operation is retried. +#[stable(feature = "rust1", since = "1.0.0")] pub fn copy<R: Read, W: Write>(r: &mut R, w: &mut W) -> io::Result<u64> { let mut buf = [0; super::DEFAULT_BUF_SIZE]; let mut written = 0; @@ -43,26 +44,37 @@ pub fn copy<R: Read, W: Write>(r: &mut R, w: &mut W) -> io::Result<u64> { } /// A reader which is always at EOF. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Empty { _priv: () } /// Creates an instance of an empty reader. /// /// All reads from the returned reader will return `Ok(0)`. +#[stable(feature = "rust1", since = "1.0.0")] pub fn empty() -> Empty { Empty { _priv: () } } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for Empty { fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Ok(0) } } +#[stable(feature = "rust1", since = "1.0.0")] +impl BufRead for Empty { + fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) } + fn consume(&mut self, _n: usize) {} +} /// A reader which infinitely yields one byte. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Repeat { byte: u8 } /// Creates an instance of a reader that infinitely repeats one byte. /// /// All reads from this reader will succeed by filling the specified buffer with /// the given byte. +#[stable(feature = "rust1", since = "1.0.0")] pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } } +#[stable(feature = "rust1", since = "1.0.0")] impl Read for Repeat { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { for slot in buf.iter_mut() { @@ -73,14 +85,17 @@ impl Read for Repeat { } /// A writer which will move data into the void. +#[stable(feature = "rust1", since = "1.0.0")] pub struct Sink { _priv: () } /// Creates an instance of a writer which will successfully consume all data. /// /// All calls to `write` on the returned instance will return `Ok(buf.len())` /// and the contents of the buffer will not be inspected. +#[stable(feature = "rust1", since = "1.0.0")] pub fn sink() -> Sink { Sink { _priv: () } } +#[stable(feature = "rust1", since = "1.0.0")] impl Write for Sink { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) } fn flush(&mut self) -> io::Result<()> { Ok(()) } |
