#
std/io/buffered/
mod.rs

    1//! Buffering wrappers for I/O traits
    2
    3mod bufreader;
    4mod bufwriter;
    5mod linewriter;
    6mod linewritershim;
    7
    8#[cfg(test)]
    9mod tests;
    10
    11#[stable(feature = "bufwriter_into_parts", since = "1.56.0")]
    12pub use bufwriter::WriterPanicked;
    13use linewritershim::LineWriterShim;
    14
    15#[stable(feature = "rust1", since = "1.0.0")]
    16pub use self::{bufreader::BufReader, bufwriter::BufWriter, linewriter::LineWriter};
    17use crate::io::Error;
    18use crate::{error, fmt};
    19
    20/// An error returned by [`BufWriter::into_inner`] which combines an error that
    21/// happened while writing out the buffer, and the buffered writer object
    22/// which may be used to recover from the condition.
    23///
    24/// # Examples
    25///
    26/// ```no_run
    27/// use std::io::BufWriter;
    28/// use std::net::TcpStream;
    29///
    30/// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
    31///
    32/// // do stuff with the stream
    33///
    34/// // we want to get our `TcpStream` back, so let's try:
    35///
    36/// let stream = match stream.into_inner() {
    37///     Ok(s) => s,
    38///     Err(e) => {
    39///         // Here, e is an IntoInnerError
    40///         panic!("An error occurred");
    41///     }
    42/// };
    43/// ```
    44#[derive(Debug)]
    45#[stable(feature = "rust1", since = "1.0.0")]
    46pub struct IntoInnerError<W>(W, Error);
    47
    48impl<W> IntoInnerError<W> {
    49    /// Constructs a new IntoInnerError
    50    fn new(writer: W, error: Error) -> Self {
    51        Self(writer, error)
    52    }
    53
    54    /// Helper to construct a new IntoInnerError; intended to help with
    55    /// adapters that wrap other adapters
    56    fn new_wrapped<W2>(self, f: impl FnOnce(W) -> W2) -> IntoInnerError<W2> {
    57        let Self(writer, error) = self;
    58        IntoInnerError::new(f(writer), error)
    59    }
    60
    61    /// Returns the error which caused the call to [`BufWriter::into_inner()`]
    62    /// to fail.
    63    ///
    64    /// This error was returned when attempting to write the internal buffer.
    65    ///
    66    /// # Examples
    67    ///
    68    /// ```no_run
    69    /// use std::io::BufWriter;
    70    /// use std::net::TcpStream;
    71    ///
    72    /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
    73    ///
    74    /// // do stuff with the stream
    75    ///
    76    /// // we want to get our `TcpStream` back, so let's try:
    77    ///
    78    /// let stream = match stream.into_inner() {
    79    ///     Ok(s) => s,
    80    ///     Err(e) => {
    81    ///         // Here, e is an IntoInnerError, let's log the inner error.
    82    ///         //
    83    ///         // We'll just 'log' to stdout for this example.
    84    ///         println!("{}", e.error());
    85    ///
    86    ///         panic!("An unexpected error occurred.");
    87    ///     }
    88    /// };
    89    /// ```
    90    #[stable(feature = "rust1", since = "1.0.0")]
    91    pub fn error(&self) -> &Error {
    92        &self.1
    93    }
    94
    95    /// Returns the buffered writer instance which generated the error.
    96    ///
    97    /// The returned object can be used for error recovery, such as
    98    /// re-inspecting the buffer.
    99    ///
    100    /// # Examples
    101    ///
    102    /// ```no_run
    103    /// use std::io::BufWriter;
    104    /// use std::net::TcpStream;
    105    ///
    106    /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
    107    ///
    108    /// // do stuff with the stream
    109    ///
    110    /// // we want to get our `TcpStream` back, so let's try:
    111    ///
    112    /// let stream = match stream.into_inner() {
    113    ///     Ok(s) => s,
    114    ///     Err(e) => {
    115    ///         // Here, e is an IntoInnerError, let's re-examine the buffer:
    116    ///         let buffer = e.into_inner();
    117    ///
    118    ///         // do stuff to try to recover
    119    ///
    120    ///         // afterwards, let's just return the stream
    121    ///         buffer.into_inner().unwrap()
    122    ///     }
    123    /// };
    124    /// ```
    125    #[stable(feature = "rust1", since = "1.0.0")]
    126    pub fn into_inner(self) -> W {
    127        self.0
    128    }
    129
    130    /// Consumes the [`IntoInnerError`] and returns the error which caused the call to
    131    /// [`BufWriter::into_inner()`] to fail.  Unlike `error`, this can be used to
    132    /// obtain ownership of the underlying error.
    133    ///
    134    /// # Example
    135    /// ```
    136    /// use std::io::{BufWriter, ErrorKind, Write};
    137    ///
    138    /// let mut not_enough_space = [0u8; 10];
    139    /// let mut stream = BufWriter::new(not_enough_space.as_mut());
    140    /// write!(stream, "this cannot be actually written").unwrap();
    141    /// let into_inner_err = stream.into_inner().expect_err("now we discover it's too small");
    142    /// let err = into_inner_err.into_error();
    143    /// assert_eq!(err.kind(), ErrorKind::WriteZero);
    144    /// ```
    145    #[stable(feature = "io_into_inner_error_parts", since = "1.55.0")]
    146    pub fn into_error(self) -> Error {
    147        self.1
    148    }
    149
    150    /// Consumes the [`IntoInnerError`] and returns the error which caused the call to
    151    /// [`BufWriter::into_inner()`] to fail, and the underlying writer.
    152    ///
    153    /// This can be used to simply obtain ownership of the underlying error; it can also be used for
    154    /// advanced error recovery.
    155    ///
    156    /// # Example
    157    /// ```
    158    /// use std::io::{BufWriter, ErrorKind, Write};
    159    ///
    160    /// let mut not_enough_space = [0u8; 10];
    161    /// let mut stream = BufWriter::new(not_enough_space.as_mut());
    162    /// write!(stream, "this cannot be actually written").unwrap();
    163    /// let into_inner_err = stream.into_inner().expect_err("now we discover it's too small");
    164    /// let (err, recovered_writer) = into_inner_err.into_parts();
    165    /// assert_eq!(err.kind(), ErrorKind::WriteZero);
    166    /// assert_eq!(recovered_writer.buffer(), b"t be actually written");
    167    /// ```
    168    #[stable(feature = "io_into_inner_error_parts", since = "1.55.0")]
    169    pub fn into_parts(self) -> (Error, W) {
    170        (self.1, self.0)
    171    }
    172}
    173
    174#[stable(feature = "rust1", since = "1.0.0")]
    175impl<W> From<IntoInnerError<W>> for Error {
    176    fn from(iie: IntoInnerError<W>) -> Error {
    177        iie.1
    178    }
    179}
    180
    181#[stable(feature = "rust1", since = "1.0.0")]
    182impl<W: Send + fmt::Debug> error::Error for IntoInnerError<W> {
    183    #[allow(deprecated, deprecated_in_future)]
    184    fn description(&self) -> &str {
    185        error::Error::description(self.error())
    186    }
    187}
    188
    189#[stable(feature = "rust1", since = "1.0.0")]
    190impl<W> fmt::Display for IntoInnerError<W> {
    191    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    192        self.error().fmt(f)
    193    }
    194}