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}