/// [`flush`]: BufWriter::flush
#[stable(feature = "rust1", since = "1.0.0")]
pub struct BufWriter<W: Write> {
- inner: Option<W>,
+ inner: W,
// The buffer. Avoid using this like a normal `Vec` in common code paths.
// That is, don't use `buf.push`, `buf.extend_from_slice`, or any other
// methods that require bounds checking or the like. This makes an enormous
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn with_capacity(capacity: usize, inner: W) -> BufWriter<W> {
- BufWriter { inner: Some(inner), buf: Vec::with_capacity(capacity), panicked: false }
+ BufWriter { inner, buf: Vec::with_capacity(capacity), panicked: false }
}
/// Send data in our local buffer into the inner writer, looping as
}
let mut guard = BufGuard::new(&mut self.buf);
- let inner = self.inner.as_mut().unwrap();
while !guard.done() {
self.panicked = true;
- let r = inner.write(guard.remaining());
+ let r = self.inner.write(guard.remaining());
self.panicked = false;
match r {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn get_ref(&self) -> &W {
- self.inner.as_ref().unwrap()
+ &self.inner
}
/// Gets a mutable reference to the underlying writer.
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn get_mut(&mut self) -> &mut W {
- self.inner.as_mut().unwrap()
+ &mut self.inner
}
/// Returns a reference to the internally buffered data.
pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
match self.flush_buf() {
Err(e) => Err(IntoInnerError::new(self, e)),
- Ok(()) => Ok(self.inner.take().unwrap()),
+ Ok(()) => Ok(self.into_parts().0),
}
}
/// In this case, we return `WriterPanicked` for the buffered data (from which the buffer
/// contents can still be recovered).
///
- /// `into_raw_parts` makes no attempt to flush data and cannot fail.
+ /// `into_parts` makes no attempt to flush data and cannot fail.
///
/// # Examples
///
/// let mut stream = BufWriter::new(buffer.as_mut());
/// write!(stream, "too much data").unwrap();
/// stream.flush().expect_err("it doesn't fit");
- /// let (recovered_writer, buffered_data) = stream.into_raw_parts();
+ /// let (recovered_writer, buffered_data) = stream.into_parts();
/// assert_eq!(recovered_writer.len(), 0);
/// assert_eq!(&buffered_data.unwrap(), b"ata");
/// ```
#[unstable(feature = "bufwriter_into_raw_parts", issue = "80690")]
- pub fn into_raw_parts(mut self) -> (W, Result<Vec<u8>, WriterPanicked>) {
+ pub fn into_parts(mut self) -> (W, Result<Vec<u8>, WriterPanicked>) {
let buf = mem::take(&mut self.buf);
let buf = if !self.panicked { Ok(buf) } else { Err(WriterPanicked { buf }) };
- (self.inner.take().unwrap(), buf)
+
+ // SAFETY: forget(self) prevents double dropping inner
+ let inner = unsafe { ptr::read(&mut self.inner) };
+ mem::forget(self);
+
+ (inner, buf)
}
// Ensure this function does not get inlined into `write`, so that it
}
#[unstable(feature = "bufwriter_into_raw_parts", issue = "80690")]
-/// Error returned for the buffered data from `BufWriter::into_raw_parts`, when the underlying
+/// Error returned for the buffered data from `BufWriter::into_parts`, when the underlying
/// writer has previously panicked. Contains the (possibly partly written) buffered data.
///
/// # Example
/// stream.flush().unwrap()
/// }));
/// assert!(result.is_err());
-/// let (recovered_writer, buffered_data) = stream.into_raw_parts();
+/// let (recovered_writer, buffered_data) = stream.into_parts();
/// assert!(matches!(recovered_writer, PanickingWriter));
/// assert_eq!(buffered_data.unwrap_err().into_inner(), b"some data");
/// ```
{
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("BufWriter")
- .field("writer", &self.inner.as_ref().unwrap())
+ .field("writer", &self.inner)
.field("buffer", &format_args!("{}/{}", self.buf.len(), self.buf.capacity()))
.finish()
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<W: Write> Drop for BufWriter<W> {
fn drop(&mut self) {
- if self.inner.is_some() && !self.panicked {
+ if !self.panicked {
// dtors should not panic, so we ignore a failed flush
let _r = self.flush_buf();
}