BorrowedBuffer

Struct BorrowedBuffer 

Source
pub(crate) struct BorrowedBuffer<'data> {
    data: &'data mut [MaybeUninit<u8>],
    filled: u16,
}
Expand description

A borrowed buffer for writing into an uninitialized slice of bytes.

This can be used with, e.g., an ArrayBuffer as backing storage. This type will managed actually writing to the backing storage, keeping track of how much data has been written and exposing a safe API.

This type is principally used in Jiff’s printer implementations. In particular, this helps printers generate tighter and more efficient code. Once printing is done, the data in the buffer is then copied to the caller provided implementation of jiff::fmt::Write. This double write is unfortunate, but it turned out that threading a jiff::fmt::Write down through the printers and using it directly leads to slower code overall and more code bloat. This is because a BorrowedBuffer is an incredibly lightweight abstraction that never has to deal with I/O or growing an allocation.

§Design

  • Requires valid UTF-8 so that we can provide higher level safe APIs for interfacing with String.
  • Specifically panics when a write would exceed available capacity. This introduces a branch, but effectively decouples “get the maximum size correct” from “is memory safe.”

Fields§

§data: &'data mut [MaybeUninit<u8>]§filled: u16

Implementations§

Source§

impl<'data> BorrowedBuffer<'data>

Source

pub(crate) fn with_writer<const N: usize>( wtr: &mut dyn Write, _runtime_allocation: usize, with: impl FnMut(&mut BorrowedBuffer<'_>) -> Result<(), Error>, ) -> Result<(), Error>

A high level API for writing to a jiff::fmt::Write via a buffer of uninitialized bytes.

When the alloc crate feature is enabled and W provides a &mut Vec<u8>, then the buffer is extracted directly from the spare capacity of the Vec<u8>.

Source

pub(crate) fn with_vec_spare_capacity<T>( buf: &'data mut Vec<u8>, with: impl FnMut(&mut BorrowedBuffer<'_>) -> T, ) -> T

Provides a borrowed buffer into the first 255 bytes of the spare capacity in the given Vec<u8> and updates the length on Vec<u8> after the closure completes to account for any new data written.

In effect, this safely encapsulates writing into the uninitialized portion of a Vec<u8>.

If the provided closure panics, then there is no guarantee that the buf’s length will be updated to reflect what has been written. However, it is guaranteed that the length setting will not lead to undefined behavior.

Source

pub(crate) fn from_vec_spare_capacity( vec: &'data mut Vec<u8>, ) -> BorrowedBuffer<'data>

Build a borrowed buffer for writing into the spare capacity of a Vec<u8> allocation.

This is limited only to the first 255 bytes of the spare capacity.

Source

pub(crate) fn write_str(&mut self, string: &str)

Write the provided string to the available space in this buffer.

§Panics

When the available space is shorter than the length of the provided string. That is, when capacity() - filled().len() < string.len().

Source

pub(crate) fn write_char(&mut self, ch: char)

Writes the given Unicode scalar value (as UTF-8) to this writer.

§Panics

When the available space is shorter than the UTF-8 encoding of the given Unicode scalar value (up to and including 4 bytes).

Source

pub(crate) fn write_ascii_char(&mut self, byte: u8)

Writes the given ASCII byte to this writer.

§Panics

When the available space is shorter than 1 or if byte is not ASCII.

Source

pub(crate) fn write_int(&mut self, n: impl Into<u64>)

Writes the given u8 integer to this buffer. No padding is performed.

§Panics

When the available space is insufficient to encode the number of digits in the decimal representation of n.

Source

pub(crate) fn write_int_pad0(&mut self, n: impl Into<u64>, pad_len: u8)

Writes the given u8 integer to this buffer using the given padding.

The maximum allowed padding is 20. Any values bigger than that are silently clamped to 20.

This always pads with zeroes.

§Panics

When the available space is insufficient to encode the number of digits in the decimal representation of n.

This also panics when pad_byte is not ASCII.

Source

pub(crate) fn write_int_pad( &mut self, n: impl Into<u64>, pad_byte: u8, pad_len: u8, )

Writes the given u8 integer to this buffer using the given padding.

The maximum allowed padding is 20. Any values bigger than that are silently clamped to 20.

§Panics

When the available space is insufficient to encode the number of digits in the decimal representation of n.

This also panics when pad_byte is not ASCII.

Source

pub(crate) fn write_int1(&mut self, n: impl Into<u64>)

Writes the given integer as a 1-digit integer.

§Panics

When the available space is shorter than 1 or if n > 9.

Source

pub(crate) fn write_int_pad2(&mut self, n: impl Into<u64>)

Writes the given integer as a 2-digit zero padded integer to this buffer.

§Panics

When the available space is shorter than 2 or if n > 99.

Source

pub(crate) fn write_int_pad2_space(&mut self, n: impl Into<u64>)

Writes the given integer as a 2-digit space padded integer to this buffer.

§Panics

When the available space is shorter than 2 or if n > 99.

Source

pub(crate) fn write_int_pad4(&mut self, n: impl Into<u64>)

Writes the given integer as a 4-digit zero padded integer to this buffer.

§Panics

When the available space is shorter than 4 or if n > 9999.

Source

pub(crate) fn write_fraction(&mut self, precision: Option<u8>, n: u32)

Writes n as a fractional component to the given precision.

When precision is absent, then it is automatically detected based on the value of n.

When precision is bigger than 9, then it is clamped to 9.

§Panics

When the available space is shorter than the number of digits required to write n as a fractional value.

Source

pub(crate) fn clear(&mut self)

Clears this buffer so that there are no filled bytes.

Note that no actual clearing of data is done, but this does lose track of data that has been initialized and data that hasn’t been initialized.

Source

pub(crate) fn filled(&self) -> &str

Returns the filled portion of this buffer.

Source

fn available(&mut self) -> &mut [MaybeUninit<u8>]

Returns the available space in this buffer.

Source

fn len(&self) -> usize

Return the length of the “filled” in bytes.

This is always equivalent to the length of the slice returned by BorrowedBuffer::filled.

Source

fn available_capacity(&self) -> usize

Return the total unused capacity available to this buffer.

Source

fn capacity(&self) -> usize

Return the total capacity available to this buffer.

Trait Implementations§

Source§

impl<'data> Debug for BorrowedBuffer<'data>

Source§

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

Formats the value using the given formatter. Read more
Source§

impl<'data> From<&'data mut [MaybeUninit<u8>]> for BorrowedBuffer<'data>

Construct a borrowed buffer directly from a slice of uninitialized data.

§Panics

When the slice exceeds the maximum capacity supported by BorrowedBuffer.

Source§

fn from(data: &'data mut [MaybeUninit<u8>]) -> BorrowedBuffer<'data>

Converts to this type from the input type.
Source§

impl<'data, const N: usize> From<&'data mut [MaybeUninit<u8>; N]> for BorrowedBuffer<'data>

Construct a borrowed buffer directly from an array of uninitialized data.

§Panics

When the array exceeds the maximum capacity supported by BorrowedBuffer.

Source§

fn from(data: &'data mut [MaybeUninit<u8>; N]) -> BorrowedBuffer<'data>

Converts to this type from the input type.
Source§

impl<'data> From<&'data mut [u8]> for BorrowedBuffer<'data>

Construct a borrowed buffer for writing into a &mut [u8].

This typically isn’t useful on its own since &mut [u8] is already guaranteed to be initialized and doesn’t require handling with care. However, this is useful when using with APIs that expect a BorrowedBuffer.

§Panics

When the slice exceeds the maximum capacity supported by BorrowedBuffer.

Source§

fn from(data: &'data mut [u8]) -> BorrowedBuffer<'data>

Converts to this type from the input type.

Auto Trait Implementations§

§

impl<'data> Freeze for BorrowedBuffer<'data>

§

impl<'data> RefUnwindSafe for BorrowedBuffer<'data>

§

impl<'data> Send for BorrowedBuffer<'data>

§

impl<'data> Sync for BorrowedBuffer<'data>

§

impl<'data> Unpin for BorrowedBuffer<'data>

§

impl<'data> !UnwindSafe for BorrowedBuffer<'data>

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

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

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

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

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

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

Performs the conversion.