Struct LineWriterShim

pub(in ::io::buffered) struct LineWriterShim<'a, W: ?Sized + Write> { pub(in ::io::buffered::linewritershim) buffer: &'a mut BufWriter<W> }

Private helper struct for implementing the line-buffered writing logic.

This shim temporarily wraps a BufWriter, and uses its internals to implement a line-buffered writer (specifically by using the internal methods like write_to_buf and flush_buf). In this way, a more efficient abstraction can be created than one that only had access to write and flush, without needlessly duplicating a lot of the implementation details of BufWriter. This also allows existing BufWriters to be temporarily given line-buffering logic; this is what enables Stdout to be alternately in line-buffered or block-buffered mode.

Fields

buffer: &'a mut BufWriter<W>

Implementations

impl<'a, W: ?Sized + Write> LineWriterShim<'a, W>

fn new(buffer: &'a mut BufWriter<W>) -> Self
fn inner(&self) -> &W

Gets a reference to the inner writer (that is, the writer wrapped by the BufWriter).

fn inner_mut(&mut self) -> &mut W

Gets a mutable reference to the inner writer (that is, the writer wrapped by the BufWriter). Be careful with this writer, as writes to it will bypass the buffer.

fn buffered(&self) -> &[u8]

Gets the content currently buffered in self.buffer

fn flush_if_completed_line(&mut self) -> Result<()>

Flushes the buffer if and only if the last byte is a newline (indicating that an earlier write only succeeded partially, and we want to retry flushing the buffered line before continuing with a subsequent write).

fn write_vectored_scanned(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize>

Vectored line-buffered write over an already-capped list of buffers.

The caller is responsible for trimming bufs to the prefix it is willing to scan (see MAX_BUFS_TO_SCAN). This method only ever writes or buffers bytes from bufs, so any newline it might bury in the BufWriter is one it has itself scanned for -- buffers the caller dropped past the cap can never end up stuck in the buffer. Bytes not accounted for in the return value are left for the next call.

Trait Implementations

impl<'a, W: ?Sized + Write> Write for LineWriterShim<'a, W>

fn write(&mut self, buf: &[u8]) -> Result<usize>

Writes some data into this BufWriter with line buffering.

This means that, if any newlines are present in the data, the data up to the last newline is sent directly to the underlying writer, and data after it is buffered. Returns the number of bytes written.

This function operates on a "best effort basis"; in keeping with the convention of Write::write, it makes at most one attempt to write new data to the underlying writer. If that write only reports a partial success, the remaining data will be buffered.

Because this function attempts to send completed lines to the underlying writer, it will also flush the existing buffer if it ends with a newline, even if the incoming data does not contain any newlines.

fn flush(&mut self) -> Result<()>
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize>

Writes some vectored data into this BufWriter with line buffering.

This means that, if any newlines are present in the data, the data up to and including the buffer containing the last newline is sent directly to the inner writer, and the data after it is buffered. Returns the number of bytes written.

This function operates on a "best effort basis"; in keeping with the convention of Write::write, it makes at most one attempt to write new data to the underlying writer.

Because this function attempts to send completed lines to the underlying writer, it will also flush the existing buffer if it contains any newlines.

Because sorting through an array of IoSlice can be a bit convoluted, This method differs from write in the following ways:

  • It attempts to write the full content of all the buffers up to and including the one containing the last newline. This means that it may attempt to write a partial line, that buffer has data past the newline.
  • If the write only reports partial success, it does not attempt to find the precise location of the written bytes and buffer the rest.

If the underlying vector doesn't support vectored writing, we instead simply write the first non-empty buffer with write. This way, we get the benefits of more granular partial-line handling without losing anything in efficiency

fn is_write_vectored(&self) -> bool
fn write_all(&mut self, buf: &[u8]) -> Result<()>

Writes some data into this BufWriter with line buffering.

This means that, if any newlines are present in the data, the data up to the last newline is sent directly to the underlying writer, and data after it is buffered.

Because this function attempts to send completed lines to the underlying writer, it will also flush the existing buffer if it contains any newlines, even if the incoming data does not contain any newlines.

impl<'a, W: Debug + ?Sized + Write> Debug for LineWriterShim<'a, W>

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Auto Trait Implementations

impl<'a, W> !UnwindSafe for LineWriterShim<'a, W>

impl<'a, W> Freeze for LineWriterShim<'a, W> where &'a mut BufWriter<W>: Freeze, W: ?Sized,

impl<'a, W> RefUnwindSafe for LineWriterShim<'a, W> where &'a mut BufWriter<W>: RefUnwindSafe, W: ?Sized,

impl<'a, W> Send for LineWriterShim<'a, W> where &'a mut BufWriter<W>: Send, W: ?Sized,

impl<'a, W> Sync for LineWriterShim<'a, W> where &'a mut BufWriter<W>: Sync, W: ?Sized,

impl<'a, W> Unpin for LineWriterShim<'a, W> where &'a mut BufWriter<W>: Unpin, W: ?Sized,

impl<'a, W> UnsafeUnpin for LineWriterShim<'a, W> where &'a mut BufWriter<W>: UnsafeUnpin, W: ?Sized,

Blanket Implementations

impl<T> Any for LineWriterShim<'a, W> where T: 'static + ?Sized,

fn type_id(&self) -> TypeId

impl<T> Borrow<T> for LineWriterShim<'a, W> where T: ?Sized,

fn borrow(&self) -> &T

impl<T> BorrowMut<T> for LineWriterShim<'a, W> where T: ?Sized,

fn borrow_mut(&mut self) -> &mut T

impl<T> From<T> for LineWriterShim<'a, W>

fn from(t: T) -> T

Returns the argument unchanged.

impl<T> SizeHint for LineWriterShim<'a, W> where T: ?Sized,

fn lower_bound(&self) -> usize
fn upper_bound(&self) -> Option<usize>

impl<T> SizedTypeProperties for LineWriterShim<'a, W>

impl<T, U> Into<U> for LineWriterShim<'a, W> where U: From<T>,

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

impl<T, U> TryFrom<U> for LineWriterShim<'a, W> where U: Into<T>,

type Error = Infallible;
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

impl<T, U> TryInto<U> for LineWriterShim<'a, W> where U: TryFrom<T>,

type Error = <U as TryFrom<T>>::Error;
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>