pub unsafe trait Reader<'a> {
const BORROW_KINDS: u8 = 0;
Show 13 methods
// Required method
fn copy_into_slice(&mut self, dst: &mut [u8]) -> ReadResult<()>;
// Provided methods
fn supports_borrow(&self, kind: BorrowKind) -> bool { ... }
fn take_array<const N: usize>(&mut self) -> ReadResult<[u8; N]> { ... }
fn take_byte(&mut self) -> ReadResult<u8> { ... }
fn take_borrowed(&mut self, len: usize) -> ReadResult<&'a [u8]> { ... }
fn take_borrowed_mut(&mut self, len: usize) -> ReadResult<&'a mut [u8]> { ... }
fn take_scoped(&mut self, len: usize) -> ReadResult<&[u8]> { ... }
unsafe fn as_trusted_for(
&mut self,
n_bytes: usize,
) -> ReadResult<impl Reader<'a>> { ... }
unsafe fn as_trusted_for_seq(
&mut self,
len: usize,
size: usize,
) -> Result<impl Reader<'a>, ReadError> { ... }
fn by_ref(&mut self) -> impl Reader<'a> { ... }
fn copy_into_uninit_slice(
&mut self,
dst: &mut [MaybeUninit<u8>],
) -> ReadResult<()> { ... }
unsafe fn copy_into_t<T>(
&mut self,
dst: &mut MaybeUninit<T>,
) -> ReadResult<()> { ... }
unsafe fn copy_into_slice_t<T>(
&mut self,
dst: &mut [MaybeUninit<T>],
) -> ReadResult<()> { ... }
}Expand description
Trait for structured reading of bytes from a source into potentially uninitialized memory.
§Borrowing semantics
- Only implement
Reader::take_borrowedorReader::take_borrowed_mutfor sources where stable borrows into the backing storage are possible. - Callers should prefer
Reader::copy_into_sliceortake_*methods to remain compatible with readers that don’t support borrowing, if possible. - Returns
ReadError::UnsupportedBorrowfor readers that do not support borrowing.
§Performance
The default Reader::copy_into_uninit_slice implementation initializes
the destination before delegating to Reader::copy_into_slice.
Implementors that can safely write directly into MaybeUninit<u8> storage
should override it to avoid this initialization. Such overrides must still
initialize every destination byte before returning Ok(()).
§Safety
Implementors must ensure that:
- If
copy_into_uninit_slicereturnsOk(()), every element of the destination has been initialized. - All safe methods uphold Rust’s validity, aliasing, and lifetime rules for every safe input. Callers are not responsible for proving that destination buffers do not overlap internal storage.
- References returned by borrowing methods remain valid for their documented lifetimes.
- Any unchecked reader returned by
as_trusted_forobeys that method’s documented bounds contract.
Provided Associated Constants§
Sourceconst BORROW_KINDS: u8 = 0
const BORROW_KINDS: u8 = 0
Borrow capabilities of this reader.
A bitmask of BorrowKind values indicating which kinds of borrows are supported.
Users of Reader can call Reader::supports_borrow to check if a borrow kind
is supported.
Required Methods§
Sourcefn copy_into_slice(&mut self, dst: &mut [u8]) -> ReadResult<()>
fn copy_into_slice(&mut self, dst: &mut [u8]) -> ReadResult<()>
Attempts to copy and consume exactly dst.len() bytes.
On success, exactly dst.len() bytes are consumed and every element of
dst contains the corresponding byte. On error, some bytes may have been
consumed; dst remains initialized, but its contents are unspecified.
Provided Methods§
Sourcefn supports_borrow(&self, kind: BorrowKind) -> bool
fn supports_borrow(&self, kind: BorrowKind) -> bool
Checks if this reader supports the given borrow kind.
§Examples
let reader = [1, 2, 3, 4, 5];
assert!(reader.as_slice().supports_borrow(BorrowKind::Backing));
let mut reader = [1, 2, 3, 4, 5];
assert!(reader.as_mut_slice().supports_borrow(BorrowKind::BackingMut));
let reader = Cursor::new([1, 2, 3, 4, 5]);
assert!(reader.supports_borrow(BorrowKind::CallSite));
assert!(!reader.supports_borrow(BorrowKind::Backing));Sourcefn take_array<const N: usize>(&mut self) -> ReadResult<[u8; N]>
fn take_array<const N: usize>(&mut self) -> ReadResult<[u8; N]>
Return exactly N bytes as [u8; N] and advance by N.
Errors if fewer than N bytes are available.
Sourcefn take_byte(&mut self) -> ReadResult<u8>
fn take_byte(&mut self) -> ReadResult<u8>
Return the next byte and advance by 1.
Errors if the reader is exhausted.
Sourcefn take_borrowed(&mut self, len: usize) -> ReadResult<&'a [u8]>
fn take_borrowed(&mut self, len: usize) -> ReadResult<&'a [u8]>
Return a borrowed slice of exactly len bytes and advance
the reader by len.
The returned slice is tied to the reader’s backing lifetime 'a.
This means the slice may outlive the borrow of the call, and is
valid after the reader is dropped or reborrowed.
This stronger guarantee is typically only possible for readers backed
by stable storage (for example &'a [u8] or memory-mapped buffers).
Prefer Reader::take_scoped unless you specifically require a slice
that lives for 'a. Prefer Reader::copy_into_slice if you ultimately
intend to copy the slice.
Errors if the reader cannot provide len bytes or does not support
borrowing into stable storage that outlives the reader.
Sourcefn take_borrowed_mut(&mut self, len: usize) -> ReadResult<&'a mut [u8]>
fn take_borrowed_mut(&mut self, len: usize) -> ReadResult<&'a mut [u8]>
Return a mutably borrowed slice of exactly len bytes and advance
the reader by len.
The returned slice is tied to the reader’s backing lifetime 'a.
This means the slice may outlive the borrow of the call, and is
valid after the reader is dropped or reborrowed.
This stronger guarantee is typically only possible for readers backed
by stable storage (for example &'a mut [u8] or memory-mapped buffers).
Errors if the reader cannot provide len bytes or does not support
mutable borrowing into stable, mutable storage that outlives the reader.
Sourcefn take_scoped(&mut self, len: usize) -> ReadResult<&[u8]>
fn take_scoped(&mut self, len: usize) -> ReadResult<&[u8]>
Return a call-site scoped slice of exactly len bytes and advance by len.
The returned slice is tied to the borrow of self, meaning it is only
valid while the current borrow of the reader is alive. Implementations
are free to return slices backed by internal buffers or transient windows
into the underlying source.
Prefer Reader::copy_into_slice if you ultimately intend to copy the slice.
Errors for readers that don’t support call-site scoped borrowing.
Sourceunsafe fn as_trusted_for(
&mut self,
n_bytes: usize,
) -> ReadResult<impl Reader<'a>>
unsafe fn as_trusted_for( &mut self, n_bytes: usize, ) -> ReadResult<impl Reader<'a>>
Advance the parent by n_bytes and return a Reader that can elide bounds checks within
that n_bytes window.
Implementors must:
- Arrange that the returned
Trustedreader’s methods operate within thatn_byteswindow (it may buffer or prefetch arbitrarily). - Ensure that the returned reader either continues checking its bounds
normally or is backed by at least
n_bytes; otherwise, return an error.
Note:
as_trusted_foris intended for callers that know they will operate within a fixed-size window and want to avoid intermediate bounds checks.
§Safety
The caller must ensure that, through the returned reader, they do not
cause more than n_bytes bytes to be logically read or consumed
without performing additional bounds checks.
Concretely:
- The total number of bytes accessed/consumed via the
Trustedreader (copy_into_*,take_*, etc.) must be <=n_bytes.
Violating this is undefined behavior, because Trusted readers are
permitted to elide bounds checks within the n_bytes window; reading past the
n_bytes window may read past the end of the underlying buffer.
Sourceunsafe fn as_trusted_for_seq(
&mut self,
len: usize,
size: usize,
) -> Result<impl Reader<'a>, ReadError>
unsafe fn as_trusted_for_seq( &mut self, len: usize, size: usize, ) -> Result<impl Reader<'a>, ReadError>
Construct a trusted window for a sequence of length len and serialized
element size size.
Always prefer this over manual unchecked arithmetic.
§Safety
The caller must ensure that operations through the returned reader do not
logically read or consume more than len * size bytes without performing
additional bounds checks.
Sourcefn by_ref(&mut self) -> impl Reader<'a>
fn by_ref(&mut self) -> impl Reader<'a>
Get a mutable reference to the Reader.
Useful in situations where one only has an impl Reader<'de> that
needs to be passed to mulitple functions requiring impl Reader<'de>.
Always prefer this over &mut reader to avoid recursive borrows.
struct FooBar {
foo: u32,
bar: u32,
}
unsafe impl<'de, C: Config> SchemaRead<'de, C> for FooBar {
type Dst = Self;
fn read(mut reader: impl Reader<'de>, dst: &mut MaybeUninit<Self>) -> ReadResult<()> {
// `reader.by_ref()`; Good ✅
let foo = <u32 as SchemaRead<'de, C>>::get(reader.by_ref())?;
let bar = <u32 as SchemaRead<'de, C>>::get(reader)?;
dst.write(FooBar { foo, bar });
Ok(())
}
}Sourcefn copy_into_uninit_slice(
&mut self,
dst: &mut [MaybeUninit<u8>],
) -> ReadResult<()>
fn copy_into_uninit_slice( &mut self, dst: &mut [MaybeUninit<u8>], ) -> ReadResult<()>
Attempts to copy and consume exactly dst.len() bytes into potentially
uninitialized storage.
On success, exactly dst.len() bytes are consumed and every element of
dst is initialized. On error, some bytes may have been consumed; the
initialization state and contents of dst are unspecified.
The default implementation initializes the destination before calling
Reader::copy_into_slice. Implementations may override it to write directly
into uninitialized storage.
§Implementor requirements
Before returning Ok(()), implementations must initialize every element of
dst. This postcondition is required for soundness. Methods such as take_array
treat the entire destination as initialized after Ok(()).
Returning Ok(()) while any destination byte remains uninitialized may cause undefined behavior.
Sourceunsafe fn copy_into_t<T>(&mut self, dst: &mut MaybeUninit<T>) -> ReadResult<()>
unsafe fn copy_into_t<T>(&mut self, dst: &mut MaybeUninit<T>) -> ReadResult<()>
Attempts to copy and consume exactly size_of::<T>() bytes from the
Reader into dst.
§Safety
- The caller must ensure that, if this method returns
Ok(()), the bytes copied intodstform a valid representation ofTbeforedstis treated as initialized. This includes all validity and provenance requirements ofT. - The caller must ensure that the memory occupied by
dstdoes not overlap the source bytes accessed by the reader.
Sourceunsafe fn copy_into_slice_t<T>(
&mut self,
dst: &mut [MaybeUninit<T>],
) -> ReadResult<()>
unsafe fn copy_into_slice_t<T>( &mut self, dst: &mut [MaybeUninit<T>], ) -> ReadResult<()>
Attempts to copy and consume exactly dst.len() * size_of::<T>() bytes
from the Reader into dst.
§Safety
- The caller must ensure that, if this method returns
Ok(()), each consecutivesize_of::<T>()byte region copied intodstforms a valid representation ofTbefore the elements are treated as initialized. This includes all validity and provenance requirements ofT. - The caller must ensure that the memory occupied by
dstdoes not overlap the source bytes accessed by the reader.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".