io_streams/buffered/
mod.rs

1//! This file is derived from Rust's library/std/src/io/buffered at revision
2//! f7801d6c7cc19ab22bdebcc8efa894a564c53469.
3//!
4//! Buffering wrappers for I/O traits.
5//!
6//! This differs from [`bufreaderwriter`] in not requiring or implementing
7//! `Seek`. This crate is meant for interactive streams, and not files.
8//!
9//! [`bufreaderwriter`]: https://crates.io/crates/bufreaderwriter
10
11mod buf_duplexer;
12mod buf_reader_line_writer;
13mod buf_reader_line_writer_shim;
14
15use std::io::Error;
16use std::{error, fmt};
17
18pub use buf_duplexer::BufDuplexer;
19pub use buf_reader_line_writer::BufReaderLineWriter;
20use buf_reader_line_writer_shim::BufReaderLineWriterShim;
21
22/// The value from `library/std/src/sys_common/io.rs`.
23pub(super) const DEFAULT_BUF_SIZE: usize = 8 * 1024;
24
25/// An error returned by [`BufWriter::into_inner`] which combines an error that
26/// happened while writing out the buffer, and the buffered writer object
27/// which may be used to recover from the condition.
28///
29/// # Examples
30///
31/// ```no_run
32/// use std::io::BufWriter;
33/// use std::net::TcpStream;
34///
35/// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
36///
37/// // do stuff with the stream
38///
39/// // we want to get our `TcpStream` back, so let's try:
40///
41/// let stream = match stream.into_inner() {
42///     Ok(s) => s,
43///     Err(e) => {
44///         // Here, e is an `IntoInnerError`
45///         panic!("An error occurred");
46///     }
47/// };
48/// ```
49///
50/// [`BufWriter::into_inner`]: https://doc.rust-lang.org/std/io/struct.BufWriter.html#method.into_inner
51#[derive(Debug)]
52pub struct IntoInnerError<W>(W, Error);
53
54impl<W> IntoInnerError<W> {
55    /// Construct a new `IntoInnerError`
56    fn new(writer: W, error: Error) -> Self {
57        Self(writer, error)
58    }
59
60    /// Helper to construct a new `IntoInnerError`; intended to help with`
61    /// adapters that wrap other adapters
62    fn new_wrapped<W2>(self, f: impl FnOnce(W) -> W2) -> IntoInnerError<W2> {
63        let Self(writer, error) = self;
64        IntoInnerError::new(f(writer), error)
65    }
66
67    /// Returns the error which caused the call to [`BufWriter::into_inner()`]
68    /// to fail.
69    ///
70    /// This error was returned when attempting to write the internal buffer.
71    ///
72    /// # Examples
73    ///
74    /// ```no_run
75    /// use std::io::BufWriter;
76    /// use std::net::TcpStream;
77    ///
78    /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
79    ///
80    /// // do stuff with the stream
81    ///
82    /// // we want to get our `TcpStream` back, so let's try:
83    ///
84    /// let stream = match stream.into_inner() {
85    ///     Ok(s) => s,
86    ///     Err(e) => {
87    ///         // Here, e is an `IntoInnerError`, let's log the inner error.
88    ///         //
89    ///         // We'll just 'log' to stdout for this example.
90    ///         println!("{}", e.error());
91    ///
92    ///         panic!("An unexpected error occurred.");
93    ///     }
94    /// };
95    /// ```
96    ///
97    /// [`BufWriter::into_inner()`]: std::io::BufWriter::into_inner
98    pub fn error(&self) -> &Error {
99        &self.1
100    }
101
102    /// Returns the buffered writer instance which generated the error.
103    ///
104    /// The returned object can be used for error recovery, such as
105    /// re-inspecting the buffer.
106    ///
107    /// # Examples
108    ///
109    /// ```no_run
110    /// use std::io::BufWriter;
111    /// use std::net::TcpStream;
112    ///
113    /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
114    ///
115    /// // do stuff with the stream
116    ///
117    /// // we want to get our `TcpStream` back, so let's try:
118    ///
119    /// let stream = match stream.into_inner() {
120    ///     Ok(s) => s,
121    ///     Err(e) => {
122    ///         // Here, e is an `IntoInnerError`, let's re-examine the buffer:
123    ///         let buffer = e.into_inner();
124    ///
125    ///         // do stuff to try to recover
126    ///
127    ///         // afterwards, let's just return the stream
128    ///         buffer.into_inner().unwrap()
129    ///     }
130    /// };
131    /// ```
132    pub fn into_inner(self) -> W {
133        self.0
134    }
135}
136
137impl<W> From<IntoInnerError<W>> for Error {
138    fn from(iie: IntoInnerError<W>) -> Self {
139        iie.1
140    }
141}
142
143impl<W: Send + fmt::Debug> error::Error for IntoInnerError<W> {
144    #[allow(deprecated, deprecated_in_future)]
145    fn description(&self) -> &str {
146        error::Error::description(self.error())
147    }
148}
149
150impl<W> fmt::Display for IntoInnerError<W> {
151    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
152        self.error().fmt(f)
153    }
154}