blob: 232e388433fb000633b00e011b9aa08bb1391ce1 [file] [edit]
use crate::fmt;
/// `Empty` ignores any data written via [`Write`], and will always be empty
/// (returning zero bytes) when read via [`Read`].
///
/// [`Write`]: ../../std/io/trait.Write.html
/// [`Read`]: ../../std/io/trait.Read.html
///
/// This struct is generally created by calling [`empty()`]. Please
/// see the documentation of [`empty()`] for more details.
#[stable(feature = "rust1", since = "1.0.0")]
#[non_exhaustive]
#[derive(Copy, Clone, Debug, Default)]
pub struct Empty;
/// Creates a value that is always at EOF for reads, and ignores all data written.
///
/// All calls to [`write`] on the returned instance will return [`Ok(buf.len())`]
/// and the contents of the buffer will not be inspected.
///
/// All calls to [`read`] from the returned reader will return [`Ok(0)`].
///
/// [`Ok(buf.len())`]: Ok
/// [`Ok(0)`]: Ok
///
/// [`write`]: ../../std/io/trait.Write.html#tymethod.write
/// [`read`]: ../../std/io/trait.Read.html#tymethod.read
///
/// # Examples
///
/// ```rust
/// use std::io::{self, Write};
///
/// let buffer = vec![1, 2, 3, 5, 8];
/// let num_bytes = io::empty().write(&buffer).unwrap();
/// assert_eq!(num_bytes, 5);
/// ```
///
///
/// ```rust
/// use std::io::{self, Read};
///
/// let mut buffer = String::new();
/// io::empty().read_to_string(&mut buffer).unwrap();
/// assert!(buffer.is_empty());
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")]
pub const fn empty() -> Empty {
Empty
}
/// A reader which yields one byte over and over and over and over and over and...
///
/// This struct is generally created by calling [`repeat()`]. Please
/// see the documentation of [`repeat()`] for more details.
#[stable(feature = "rust1", since = "1.0.0")]
#[non_exhaustive]
pub struct Repeat {
#[doc(hidden)]
#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
pub 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.
///
/// # Examples
///
/// ```
/// use std::io::{self, Read};
///
/// let mut buffer = [0; 3];
/// io::repeat(0b101).read_exact(&mut buffer).unwrap();
/// assert_eq!(buffer, [0b101, 0b101, 0b101]);
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")]
pub const fn repeat(byte: u8) -> Repeat {
Repeat { byte }
}
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Repeat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Repeat").finish_non_exhaustive()
}
}
/// A writer which will move data into the void.
///
/// This struct is generally created by calling [`sink()`]. Please
/// see the documentation of [`sink()`] for more details.
#[stable(feature = "rust1", since = "1.0.0")]
#[non_exhaustive]
#[derive(Copy, Clone, Debug, Default)]
pub struct Sink;
/// 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.
///
/// [`write`]: ../../std/io/trait.Write.html#tymethod.write
/// [`Ok(buf.len())`]: Ok
///
/// # Examples
///
/// ```rust
/// use std::io::{self, Write};
///
/// let buffer = vec![1, 2, 3, 5, 8];
/// let num_bytes = io::sink().write(&buffer).unwrap();
/// assert_eq!(num_bytes, 5);
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")]
pub const fn sink() -> Sink {
Sink
}
/// Adapter to chain together two readers.
///
/// This struct is generally created by calling [`chain`] on a reader.
/// Please see the documentation of [`chain`] for more details.
///
/// [`chain`]: ../../std/io/trait.Read.html#method.chain
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Debug)]
#[non_exhaustive]
pub struct Chain<T, U> {
#[doc(hidden)]
#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
pub first: T,
#[doc(hidden)]
#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
pub second: U,
#[doc(hidden)]
#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
pub done_first: bool,
}
impl<T, U> Chain<T, U> {
/// Consumes the `Chain`, returning the wrapped readers.
///
/// # Examples
///
/// ```no_run
/// use std::io;
/// use std::io::prelude::*;
/// use std::fs::File;
///
/// fn main() -> io::Result<()> {
/// let mut foo_file = File::open("foo.txt")?;
/// let mut bar_file = File::open("bar.txt")?;
///
/// let chain = foo_file.chain(bar_file);
/// let (foo_file, bar_file) = chain.into_inner();
/// Ok(())
/// }
/// ```
#[stable(feature = "more_io_inner_methods", since = "1.20.0")]
pub fn into_inner(self) -> (T, U) {
(self.first, self.second)
}
/// Gets references to the underlying readers in this `Chain`.
///
/// Care should be taken to avoid modifying the internal I/O state of the
/// underlying readers as doing so may corrupt the internal state of this
/// `Chain`.
///
/// # Examples
///
/// ```no_run
/// use std::io;
/// use std::io::prelude::*;
/// use std::fs::File;
///
/// fn main() -> io::Result<()> {
/// let mut foo_file = File::open("foo.txt")?;
/// let mut bar_file = File::open("bar.txt")?;
///
/// let chain = foo_file.chain(bar_file);
/// let (foo_file, bar_file) = chain.get_ref();
/// Ok(())
/// }
/// ```
#[stable(feature = "more_io_inner_methods", since = "1.20.0")]
pub fn get_ref(&self) -> (&T, &U) {
(&self.first, &self.second)
}
/// Gets mutable references to the underlying readers in this `Chain`.
///
/// Care should be taken to avoid modifying the internal I/O state of the
/// underlying readers as doing so may corrupt the internal state of this
/// `Chain`.
///
/// # Examples
///
/// ```no_run
/// use std::io;
/// use std::io::prelude::*;
/// use std::fs::File;
///
/// fn main() -> io::Result<()> {
/// let mut foo_file = File::open("foo.txt")?;
/// let mut bar_file = File::open("bar.txt")?;
///
/// let mut chain = foo_file.chain(bar_file);
/// let (foo_file, bar_file) = chain.get_mut();
/// Ok(())
/// }
/// ```
#[stable(feature = "more_io_inner_methods", since = "1.20.0")]
pub fn get_mut(&mut self) -> (&mut T, &mut U) {
(&mut self.first, &mut self.second)
}
}
#[doc(hidden)]
#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
#[must_use]
#[inline]
pub const fn chain<T, U>(first: T, second: U) -> Chain<T, U> {
Chain { first, second, done_first: false }
}
/// Reader adapter which limits the bytes read from an underlying reader.
///
/// This struct is generally created by calling [`take`] on a reader.
/// Please see the documentation of [`take`] for more details.
///
/// [`take`]: ../../std/io/trait.Read.html#method.take
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Debug)]
#[non_exhaustive]
pub struct Take<T> {
#[doc(hidden)]
#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
pub inner: T,
#[doc(hidden)]
#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
pub len: u64,
#[doc(hidden)]
#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
pub limit: u64,
}
impl<T> Take<T> {
/// Returns the number of bytes that can be read before this instance will
/// return EOF.
///
/// # Note
///
/// This instance may reach `EOF` after reading fewer bytes than indicated by
/// this method if the underlying [`Read`] instance reaches EOF.
///
/// [`Read`]: ../../std/io/trait.Read.html
///
/// # Examples
///
/// ```no_run
/// use std::io;
/// use std::io::prelude::*;
/// use std::fs::File;
///
/// fn main() -> io::Result<()> {
/// let f = File::open("foo.txt")?;
///
/// // read at most five bytes
/// let handle = f.take(5);
///
/// println!("limit: {}", handle.limit());
/// Ok(())
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn limit(&self) -> u64 {
self.limit
}
/// Returns the number of bytes read so far.
#[unstable(feature = "seek_io_take_position", issue = "97227")]
#[inline]
pub fn position(&self) -> u64 {
self.len - self.limit
}
/// Sets the number of bytes that can be read before this instance will
/// return EOF. This is the same as constructing a new `Take` instance, so
/// the amount of bytes read and the previous limit value don't matter when
/// calling this method.
///
/// # Examples
///
/// ```no_run
/// use std::io;
/// use std::io::prelude::*;
/// use std::fs::File;
///
/// fn main() -> io::Result<()> {
/// let f = File::open("foo.txt")?;
///
/// // read at most five bytes
/// let mut handle = f.take(5);
/// handle.set_limit(10);
///
/// assert_eq!(handle.limit(), 10);
/// Ok(())
/// }
/// ```
#[stable(feature = "take_set_limit", since = "1.27.0")]
pub fn set_limit(&mut self, limit: u64) {
self.len = limit;
self.limit = limit;
}
/// Consumes the `Take`, returning the wrapped reader.
///
/// # Examples
///
/// ```no_run
/// use std::io;
/// use std::io::prelude::*;
/// use std::fs::File;
///
/// fn main() -> io::Result<()> {
/// let mut file = File::open("foo.txt")?;
///
/// let mut buffer = [0; 5];
/// let mut handle = file.take(5);
/// handle.read(&mut buffer)?;
///
/// let file = handle.into_inner();
/// Ok(())
/// }
/// ```
#[stable(feature = "io_take_into_inner", since = "1.15.0")]
pub fn into_inner(self) -> T {
self.inner
}
/// Gets a reference to the underlying reader.
///
/// Care should be taken to avoid modifying the internal I/O state of the
/// underlying reader as doing so may corrupt the internal limit of this
/// `Take`.
///
/// # Examples
///
/// ```no_run
/// use std::io;
/// use std::io::prelude::*;
/// use std::fs::File;
///
/// fn main() -> io::Result<()> {
/// let mut file = File::open("foo.txt")?;
///
/// let mut buffer = [0; 5];
/// let mut handle = file.take(5);
/// handle.read(&mut buffer)?;
///
/// let file = handle.get_ref();
/// Ok(())
/// }
/// ```
#[stable(feature = "more_io_inner_methods", since = "1.20.0")]
pub fn get_ref(&self) -> &T {
&self.inner
}
/// Gets a mutable reference to the underlying reader.
///
/// Care should be taken to avoid modifying the internal I/O state of the
/// underlying reader as doing so may corrupt the internal limit of this
/// `Take`.
///
/// # Examples
///
/// ```no_run
/// use std::io;
/// use std::io::prelude::*;
/// use std::fs::File;
///
/// fn main() -> io::Result<()> {
/// let mut file = File::open("foo.txt")?;
///
/// let mut buffer = [0; 5];
/// let mut handle = file.take(5);
/// handle.read(&mut buffer)?;
///
/// let file = handle.get_mut();
/// Ok(())
/// }
/// ```
#[stable(feature = "more_io_inner_methods", since = "1.20.0")]
pub fn get_mut(&mut self) -> &mut T {
&mut self.inner
}
}
#[doc(hidden)]
#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
#[must_use]
#[inline]
pub const fn take<T>(inner: T, limit: u64) -> Take<T> {
Take { inner, limit, len: limit }
}