ckb_rust_std/io/buffered/
mod.rs

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