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