]> git.lizzy.rs Git - rust.git/blob - library/std/src/io/buffered/mod.rs
Rollup merge of #106835 - compiler-errors:new-solver-gat-rebase-oops, r=lcnr
[rust.git] / library / std / src / io / buffered / mod.rs
1 //! Buffering wrappers for I/O traits
2
3 mod bufreader;
4 mod bufwriter;
5 mod linewriter;
6 mod linewritershim;
7
8 #[cfg(test)]
9 mod tests;
10
11 use crate::error;
12 use crate::fmt;
13 use crate::io::Error;
14
15 #[stable(feature = "rust1", since = "1.0.0")]
16 pub use self::{bufreader::BufReader, bufwriter::BufWriter, linewriter::LineWriter};
17 use linewritershim::LineWriterShim;
18
19 #[stable(feature = "bufwriter_into_parts", since = "1.56.0")]
20 pub 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")]
48 pub struct IntoInnerError<W>(W, Error);
49
50 impl<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")]
177 impl<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")]
184 impl<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")]
192 impl<W> fmt::Display for IntoInnerError<W> {
193     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
194         self.error().fmt(f)
195     }
196 }