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}