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: u16Implementations§
Source§impl<'data> BorrowedBuffer<'data>
impl<'data> BorrowedBuffer<'data>
Sourcepub(crate) fn with_writer<const N: usize>(
wtr: &mut dyn Write,
_runtime_allocation: usize,
with: impl FnMut(&mut BorrowedBuffer<'_>) -> Result<(), Error>,
) -> Result<(), Error>
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>.
Sourcepub(crate) fn with_vec_spare_capacity<T>(
buf: &'data mut Vec<u8>,
with: impl FnMut(&mut BorrowedBuffer<'_>) -> T,
) -> T
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.
Sourcepub(crate) fn from_vec_spare_capacity(
vec: &'data mut Vec<u8>,
) -> BorrowedBuffer<'data>
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.
Sourcepub(crate) fn write_str(&mut self, string: &str)
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().
Sourcepub(crate) fn write_char(&mut self, ch: char)
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).
Sourcepub(crate) fn write_ascii_char(&mut self, byte: u8)
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.
Sourcepub(crate) fn write_int(&mut self, n: impl Into<u64>)
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.
Sourcepub(crate) fn write_int_pad0(&mut self, n: impl Into<u64>, pad_len: u8)
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.
Sourcepub(crate) fn write_int_pad(
&mut self,
n: impl Into<u64>,
pad_byte: u8,
pad_len: u8,
)
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.
Sourcepub(crate) fn write_int1(&mut self, n: impl Into<u64>)
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.
Sourcepub(crate) fn write_int_pad2(&mut self, n: impl Into<u64>)
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.
Sourcepub(crate) fn write_int_pad2_space(&mut self, n: impl Into<u64>)
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.
Sourcepub(crate) fn write_int_pad4(&mut self, n: impl Into<u64>)
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.
Sourcepub(crate) fn write_fraction(&mut self, precision: Option<u8>, n: u32)
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.
Sourcepub(crate) fn clear(&mut self)
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.
Sourcefn available(&mut self) -> &mut [MaybeUninit<u8>]
fn available(&mut self) -> &mut [MaybeUninit<u8>]
Returns the available space in this buffer.
Sourcefn len(&self) -> usize
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.
Sourcefn available_capacity(&self) -> usize
fn available_capacity(&self) -> usize
Return the total unused capacity available to this buffer.
Trait Implementations§
Source§impl<'data> Debug for BorrowedBuffer<'data>
impl<'data> Debug for BorrowedBuffer<'data>
Source§impl<'data> From<&'data mut [MaybeUninit<u8>]> for BorrowedBuffer<'data>
Construct a borrowed buffer directly from a slice of uninitialized data.
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>
fn from(data: &'data mut [MaybeUninit<u8>]) -> BorrowedBuffer<'data>
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.
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>
fn from(data: &'data mut [MaybeUninit<u8>; N]) -> BorrowedBuffer<'data>
Source§impl<'data> From<&'data mut [u8]> for BorrowedBuffer<'data>
Construct a borrowed buffer for writing into a &mut [u8].
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.