alloc/io/buffered/mod.rs
1//! Buffering wrappers for I/O traits
2
3mod bufreader;
4mod bufwriter;
5mod linewriter;
6mod linewritershim;
7
8use core::{error, fmt};
9
10#[stable(feature = "bufwriter_into_parts", since = "1.56.0")]
11pub use self::bufwriter::WriterPanicked;
12use self::linewritershim::LineWriterShim;
13#[stable(feature = "rust1", since = "1.0.0")]
14pub use self::{bufreader::BufReader, bufwriter::BufWriter, linewriter::LineWriter};
15use crate::io::Error;
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/// # #[expect(unused_mut)]
28/// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
29///
30/// // do stuff with the stream
31///
32/// // we want to get our `TcpStream` back, so let's try:
33///
34/// let stream = match stream.into_inner() {
35/// Ok(s) => s,
36/// Err(e) => {
37/// // Here, e is an IntoInnerError
38/// panic!("An error occurred");
39/// }
40/// };
41/// ```
42#[derive(Debug)]
43#[stable(feature = "rust1", since = "1.0.0")]
44pub struct IntoInnerError<W>(W, Error);
45
46impl<W> IntoInnerError<W> {
47 /// Constructs a new IntoInnerError
48 fn new(writer: W, error: Error) -> Self {
49 Self(writer, error)
50 }
51
52 /// Helper to construct a new IntoInnerError; intended to help with
53 /// adapters that wrap other adapters
54 fn new_wrapped<W2>(self, f: impl FnOnce(W) -> W2) -> IntoInnerError<W2> {
55 let Self(writer, error) = self;
56 IntoInnerError::new(f(writer), error)
57 }
58
59 /// Returns the error which caused the call to [`BufWriter::into_inner()`]
60 /// to fail.
61 ///
62 /// This error was returned when attempting to write the internal buffer.
63 ///
64 /// # Examples
65 ///
66 /// ```no_run
67 /// use std::io::BufWriter;
68 /// use std::net::TcpStream;
69 ///
70 /// # #[expect(unused_mut)]
71 /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
72 ///
73 /// // do stuff with the stream
74 ///
75 /// // we want to get our `TcpStream` back, so let's try:
76 ///
77 /// let stream = match stream.into_inner() {
78 /// Ok(s) => s,
79 /// Err(e) => {
80 /// // Here, e is an IntoInnerError, let's log the inner error.
81 /// //
82 /// // We'll just 'log' to stdout for this example.
83 /// println!("{}", e.error());
84 ///
85 /// panic!("An unexpected error occurred.");
86 /// }
87 /// };
88 /// ```
89 #[stable(feature = "rust1", since = "1.0.0")]
90 pub fn error(&self) -> &Error {
91 &self.1
92 }
93
94 /// Returns the buffered writer instance which generated the error.
95 ///
96 /// The returned object can be used for error recovery, such as
97 /// re-inspecting the buffer.
98 ///
99 /// # Examples
100 ///
101 /// ```no_run
102 /// use std::io::BufWriter;
103 /// use std::net::TcpStream;
104 ///
105 /// # #[expect(unused_mut)]
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
184#[stable(feature = "rust1", since = "1.0.0")]
185impl<W> fmt::Display for IntoInnerError<W> {
186 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
187 self.error().fmt(f)
188 }
189}