Skip to main content

wincode/io/
mod.rs

1//! [`Reader`] and [`Writer`] implementations.
2use {
3    crate::error::read_length_encoding_overflow,
4    core::{
5        mem::{self, MaybeUninit, transmute},
6        ptr,
7        slice::{from_raw_parts, from_raw_parts_mut},
8    },
9    thiserror::Error,
10};
11
12#[derive(Debug, Clone, Copy)]
13#[repr(u8)]
14pub enum BorrowKind {
15    /// Borrowed from the call site, not extending past it.
16    CallSite,
17    /// Borrowed from the backing store, extending past the call site.
18    Backing,
19    /// Mutably borrowed from the backing store, extending past the call site.
20    BackingMut,
21}
22
23impl BorrowKind {
24    #[inline]
25    pub const fn mask(self) -> u8 {
26        1u8 << (self as u8)
27    }
28}
29
30impl core::fmt::Display for BorrowKind {
31    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
32        match self {
33            BorrowKind::CallSite => f.write_str("call-site scoped borrows"),
34            BorrowKind::Backing => f.write_str("borrows extending past the call site"),
35            BorrowKind::BackingMut => f.write_str("mutable borrows extending past the call site"),
36        }
37    }
38}
39
40#[derive(Error, Debug)]
41pub enum ReadError {
42    #[error("Attempting to read {0} bytes")]
43    ReadSizeLimit(usize),
44    #[error("Unsupported borrow operation: reader does not support {0}")]
45    UnsupportedBorrow(BorrowKind),
46    #[cfg(feature = "std")]
47    #[error(transparent)]
48    Io(#[from] std::io::Error),
49}
50
51pub type ReadResult<T> = core::result::Result<T, ReadError>;
52
53#[cold]
54pub const fn read_size_limit(len: usize) -> ReadError {
55    ReadError::ReadSizeLimit(len)
56}
57
58#[inline(always)]
59pub(super) const fn transpose<const N: usize, T>(
60    src: &mut MaybeUninit<[T; N]>,
61) -> &mut [MaybeUninit<T>; N] {
62    unsafe { transmute(src) }
63}
64
65/// Trait for structured reading of bytes from a source into potentially uninitialized memory.
66///
67/// # Borrowing semantics
68/// - Only implement [`Reader::take_borrowed`] or [`Reader::take_borrowed_mut`] for sources
69///   where stable borrows into the backing storage are possible.
70/// - Callers should prefer [`Reader::copy_into_slice`] or `take_*` methods to remain
71///   compatible with readers that don't support borrowing, if possible.
72/// - Returns [`ReadError::UnsupportedBorrow`] for readers that do not support borrowing.
73///
74/// # Performance
75///
76/// The default [`Reader::copy_into_uninit_slice`] implementation initializes
77/// the destination before delegating to [`Reader::copy_into_slice`].
78/// Implementors that can safely write directly into `MaybeUninit<u8>` storage
79/// should override it to avoid this initialization. Such overrides must still
80/// initialize every destination byte before returning `Ok(())`.
81///
82/// # Safety
83///
84/// Implementors must ensure that:
85///
86/// - If `copy_into_uninit_slice` returns `Ok(())`, every element of the
87///   destination has been initialized.
88/// - All safe methods uphold Rust's validity, aliasing, and lifetime rules for
89///   every safe input. Callers are not responsible for proving that destination
90///   buffers do not overlap internal storage.
91/// - References returned by borrowing methods remain valid for their documented
92///   lifetimes.
93/// - Any unchecked reader returned by `as_trusted_for` obeys that method's
94///   documented bounds contract.
95pub unsafe trait Reader<'a> {
96    /// Borrow capabilities of this reader.
97    ///
98    /// A bitmask of [`BorrowKind`] values indicating which kinds of borrows are supported.
99    ///
100    /// Users of [`Reader`] can call [`Reader::supports_borrow`] to check if a borrow kind
101    /// is supported.
102    const BORROW_KINDS: u8 = 0;
103
104    /// Checks if this reader supports the given borrow kind.
105    ///
106    /// # Examples
107    /// ```
108    /// # use wincode::io::{Reader, BorrowKind, Cursor};
109    /// #
110    /// let reader = [1, 2, 3, 4, 5];
111    /// assert!(reader.as_slice().supports_borrow(BorrowKind::Backing));
112    ///
113    /// let mut reader = [1, 2, 3, 4, 5];
114    /// assert!(reader.as_mut_slice().supports_borrow(BorrowKind::BackingMut));
115    ///
116    /// let reader = Cursor::new([1, 2, 3, 4, 5]);
117    /// assert!(reader.supports_borrow(BorrowKind::CallSite));
118    /// assert!(!reader.supports_borrow(BorrowKind::Backing));
119    /// ```
120    #[inline]
121    fn supports_borrow(&self, kind: BorrowKind) -> bool {
122        Self::BORROW_KINDS & kind.mask() != 0
123    }
124
125    /// Return exactly `N` bytes as `[u8; N]` and advance by `N`.
126    ///
127    /// Errors if fewer than `N` bytes are available.
128    #[inline(always)]
129    fn take_array<const N: usize>(&mut self) -> ReadResult<[u8; N]> {
130        let mut ar = MaybeUninit::<[u8; N]>::uninit();
131
132        self.copy_into_uninit_slice(transpose(&mut ar))?;
133
134        // SAFETY: `copy_into_uninit_slice` returned successfully, which guarantees
135        // every element of `ar` was initialized.
136        Ok(unsafe { ar.assume_init() })
137    }
138
139    /// Return the next byte and advance by `1`.
140    ///
141    /// Errors if the reader is exhausted.
142    #[inline(always)]
143    fn take_byte(&mut self) -> ReadResult<u8> {
144        Ok(self.take_array::<1>()?[0])
145    }
146
147    /// Return a borrowed slice of exactly `len` bytes and advance
148    /// the reader by `len`.
149    ///
150    /// The returned slice is tied to the reader's backing lifetime `'a`.
151    /// This means the slice may outlive the borrow of the call, and is
152    /// valid after the reader is dropped or reborrowed.
153    ///
154    /// This stronger guarantee is typically only possible for readers backed
155    /// by stable storage (for example `&'a [u8]` or memory-mapped buffers).
156    ///
157    /// Prefer [`Reader::take_scoped`] unless you specifically require a slice
158    /// that lives for `'a`. Prefer [`Reader::copy_into_slice`] if you ultimately
159    /// intend to copy the slice.
160    ///
161    /// Errors if the reader cannot provide `len` bytes or does not support
162    /// borrowing into stable storage that outlives the reader.
163    #[expect(unused_variables)]
164    fn take_borrowed(&mut self, len: usize) -> ReadResult<&'a [u8]> {
165        Err(ReadError::UnsupportedBorrow(BorrowKind::Backing))
166    }
167
168    /// Return a mutably borrowed slice of exactly `len` bytes and advance
169    /// the reader by `len`.
170    ///
171    /// The returned slice is tied to the reader's backing lifetime `'a`.
172    /// This means the slice may outlive the borrow of the call, and is
173    /// valid after the reader is dropped or reborrowed.
174    ///
175    /// This stronger guarantee is typically only possible for readers backed
176    /// by stable storage (for example `&'a mut [u8]` or memory-mapped buffers).
177    ///
178    /// Errors if the reader cannot provide `len` bytes or does not support
179    /// mutable borrowing into stable, mutable storage that outlives the reader.
180    #[expect(unused_variables)]
181    fn take_borrowed_mut(&mut self, len: usize) -> ReadResult<&'a mut [u8]> {
182        Err(ReadError::UnsupportedBorrow(BorrowKind::BackingMut))
183    }
184
185    /// Return a call-site scoped slice of exactly `len` bytes and advance by `len`.
186    ///
187    /// The returned slice is tied to the borrow of `self`, meaning it is only
188    /// valid while the current borrow of the reader is alive. Implementations
189    /// are free to return slices backed by internal buffers or transient windows
190    /// into the underlying source.
191    ///
192    /// Prefer [`Reader::copy_into_slice`] if you ultimately intend to copy the slice.
193    ///
194    /// Errors for readers that don't support call-site scoped borrowing.
195    #[expect(unused_variables)]
196    fn take_scoped(&mut self, len: usize) -> ReadResult<&[u8]> {
197        Err(ReadError::UnsupportedBorrow(BorrowKind::CallSite))
198    }
199
200    /// Advance the parent by `n_bytes` and return a [`Reader`] that can elide bounds checks within
201    /// that `n_bytes` window.
202    ///
203    /// Implementors must:
204    /// - Arrange that the returned `Trusted` reader's methods operate within
205    ///   that `n_bytes` window (it may buffer or prefetch arbitrarily).
206    /// - Ensure that the returned reader either continues checking its bounds
207    ///   normally or is backed by at least `n_bytes`; otherwise, return an error.
208    ///
209    /// Note:
210    /// - `as_trusted_for` is intended for callers that know they will operate
211    ///   within a fixed-size window and want to avoid intermediate bounds checks.
212    ///
213    /// # Safety
214    ///
215    /// The caller must ensure that, through the returned reader, they do not
216    /// cause more than `n_bytes` bytes to be logically read or consumed
217    /// without performing additional bounds checks.
218    ///
219    /// Concretely:
220    /// - The total number of bytes accessed/consumed via the `Trusted` reader
221    ///   (`copy_into_*`, `take_*`, etc.) must be **<= `n_bytes`**.
222    ///
223    /// Violating this is undefined behavior, because `Trusted` readers are
224    /// permitted to elide bounds checks within the `n_bytes` window; reading past the
225    /// `n_bytes` window may read past the end of the underlying buffer.
226    #[expect(unused_variables)]
227    #[inline(always)]
228    unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> ReadResult<impl Reader<'a>> {
229        Ok(self)
230    }
231
232    /// Construct a trusted window for a sequence of length `len` and serialized
233    /// element size `size`.
234    ///
235    /// Always prefer this over manual unchecked arithmetic.
236    ///
237    /// # Safety
238    ///
239    /// The caller must ensure that operations through the returned reader do not
240    /// logically read or consume more than `len * size` bytes without performing
241    /// additional bounds checks.
242    ///
243    /// See [`Reader::as_trusted_for`].
244    #[inline]
245    unsafe fn as_trusted_for_seq(
246        &mut self,
247        len: usize,
248        size: usize,
249    ) -> Result<impl Reader<'a>, crate::error::ReadError> {
250        let Some(window) = len.checked_mul(size) else {
251            return Err(read_length_encoding_overflow("usize::MAX"));
252        };
253        Ok(unsafe { self.as_trusted_for(window) }?)
254    }
255
256    /// Get a mutable reference to the [`Reader`].
257    ///
258    /// Useful in situations where one only has an `impl Reader<'de>` that
259    /// needs to be passed to mulitple functions requiring `impl Reader<'de>`.
260    ///
261    /// Always prefer this over `&mut reader` to avoid recursive borrows.
262    ///
263    /// ```
264    /// # use wincode::{io::Reader, ReadResult, config::Config, SchemaRead};
265    /// # use core::mem::MaybeUninit;
266    /// struct FooBar {
267    ///     foo: u32,
268    ///     bar: u32,
269    /// }
270    ///
271    /// unsafe impl<'de, C: Config> SchemaRead<'de, C> for FooBar {
272    ///     type Dst = Self;
273    ///
274    ///     fn read(mut reader: impl Reader<'de>, dst: &mut MaybeUninit<Self>) -> ReadResult<()> {
275    ///         // `reader.by_ref()`; Good ✅
276    ///         let foo = <u32 as SchemaRead<'de, C>>::get(reader.by_ref())?;
277    ///         let bar = <u32 as SchemaRead<'de, C>>::get(reader)?;
278    ///         dst.write(FooBar { foo, bar });
279    ///         Ok(())
280    ///     }
281    /// }
282    /// ```
283    #[inline(always)]
284    fn by_ref(&mut self) -> impl Reader<'a> {
285        self
286    }
287
288    /// Attempts to copy and consume exactly `dst.len()` bytes.
289    ///
290    /// On success, exactly `dst.len()` bytes are consumed and every element of
291    /// `dst` contains the corresponding byte. On error, some bytes may have been
292    /// consumed; `dst` remains initialized, but its contents are unspecified.
293    fn copy_into_slice(&mut self, dst: &mut [u8]) -> ReadResult<()>;
294
295    /// Attempts to copy and consume exactly `dst.len()` bytes into potentially
296    /// uninitialized storage.
297    ///
298    /// On success, exactly `dst.len()` bytes are consumed and every element of
299    /// `dst` is initialized. On error, some bytes may have been consumed; the
300    /// initialization state and contents of `dst` are unspecified.
301    ///
302    /// The default implementation initializes the destination before calling
303    /// [`Reader::copy_into_slice`]. Implementations may override it to write directly
304    /// into uninitialized storage.
305    ///
306    /// # Implementor requirements
307    ///
308    /// Before returning `Ok(())`, implementations must initialize every element of
309    /// `dst`. This postcondition is required for soundness. Methods such as `take_array`
310    /// treat the entire destination as initialized after `Ok(())`.
311    /// Returning `Ok(())` while any destination byte remains uninitialized may cause undefined behavior.
312    #[inline(always)]
313    fn copy_into_uninit_slice(&mut self, dst: &mut [MaybeUninit<u8>]) -> ReadResult<()> {
314        dst.fill(MaybeUninit::new(0));
315        // SAFETY: Every element is initialized with a valid `u8`, and
316        // `MaybeUninit<u8>` has the same layout as `u8`.
317        let dst = unsafe { transmute::<&mut [MaybeUninit<u8>], &mut [u8]>(dst) };
318        self.copy_into_slice(dst)
319    }
320
321    /// Attempts to copy and consume exactly `size_of::<T>()` bytes from the
322    /// [`Reader`] into `dst`.
323    ///
324    /// # Safety
325    ///
326    /// - The caller must ensure that, if this method returns `Ok(())`, the bytes
327    ///   copied into `dst` form a valid representation of `T` before `dst` is
328    ///   treated as initialized. This includes all validity and provenance
329    ///   requirements of `T`.
330    /// - The caller must ensure that the memory occupied by `dst` does not overlap
331    ///   the source bytes accessed by the reader.
332    #[inline]
333    unsafe fn copy_into_t<T>(&mut self, dst: &mut MaybeUninit<T>) -> ReadResult<()> {
334        // SAFETY: `dst` provides `size_of::<T>()` contiguous writable bytes, and
335        // `MaybeUninit<u8>` has alignment 1.
336        let dst = unsafe {
337            from_raw_parts_mut(dst.as_mut_ptr().cast::<MaybeUninit<u8>>(), size_of::<T>())
338        };
339        self.copy_into_uninit_slice(dst)
340    }
341
342    /// Attempts to copy and consume exactly `dst.len() * size_of::<T>()` bytes
343    /// from the [`Reader`] into `dst`.
344    ///
345    /// # Safety
346    ///
347    /// - The caller must ensure that, if this method returns `Ok(())`, each
348    ///   consecutive `size_of::<T>()` byte region copied into `dst` forms a valid
349    ///   representation of `T` before the elements are treated as initialized.
350    ///   This includes all validity and provenance requirements of `T`.
351    /// - The caller must ensure that the memory occupied by `dst` does not overlap
352    ///   the source bytes accessed by the reader.
353    #[inline]
354    unsafe fn copy_into_slice_t<T>(&mut self, dst: &mut [MaybeUninit<T>]) -> ReadResult<()> {
355        let len = size_of_val(dst);
356        // SAFETY: `dst` provides `size_of_val(dst)` contiguous writable bytes,
357        // and `MaybeUninit<u8>` has alignment 1.
358        let dst = unsafe { from_raw_parts_mut(dst.as_mut_ptr().cast::<MaybeUninit<u8>>(), len) };
359        self.copy_into_uninit_slice(dst)
360    }
361}
362
363unsafe impl<'a, R: Reader<'a> + ?Sized> Reader<'a> for &mut R {
364    const BORROW_KINDS: u8 = R::BORROW_KINDS;
365
366    #[inline(always)]
367    fn supports_borrow(&self, kind: BorrowKind) -> bool {
368        (**self).supports_borrow(kind)
369    }
370
371    #[inline(always)]
372    fn by_ref(&mut self) -> impl Reader<'a> {
373        &mut **self
374    }
375
376    #[inline(always)]
377    fn take_array<const N: usize>(&mut self) -> ReadResult<[u8; N]> {
378        (*self).take_array()
379    }
380
381    #[inline(always)]
382    fn take_scoped(&mut self, len: usize) -> ReadResult<&[u8]> {
383        (*self).take_scoped(len)
384    }
385
386    #[inline(always)]
387    fn take_borrowed(&mut self, len: usize) -> ReadResult<&'a [u8]> {
388        (*self).take_borrowed(len)
389    }
390
391    #[inline(always)]
392    fn take_borrowed_mut(&mut self, len: usize) -> ReadResult<&'a mut [u8]> {
393        (*self).take_borrowed_mut(len)
394    }
395
396    #[inline(always)]
397    fn take_byte(&mut self) -> ReadResult<u8> {
398        (*self).take_byte()
399    }
400
401    #[inline(always)]
402    unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> ReadResult<impl Reader<'a>> {
403        unsafe { (*self).as_trusted_for(n_bytes) }
404    }
405
406    #[inline(always)]
407    unsafe fn as_trusted_for_seq(
408        &mut self,
409        len: usize,
410        size: usize,
411    ) -> Result<impl Reader<'a>, crate::error::ReadError> {
412        unsafe { (*self).as_trusted_for_seq(len, size) }
413    }
414
415    #[inline(always)]
416    fn copy_into_slice(&mut self, dst: &mut [u8]) -> ReadResult<()> {
417        (*self).copy_into_slice(dst)
418    }
419
420    #[inline(always)]
421    fn copy_into_uninit_slice(&mut self, dst: &mut [MaybeUninit<u8>]) -> ReadResult<()> {
422        (*self).copy_into_uninit_slice(dst)
423    }
424
425    #[inline(always)]
426    unsafe fn copy_into_t<T>(&mut self, dst: &mut MaybeUninit<T>) -> ReadResult<()> {
427        unsafe { (*self).copy_into_t(dst) }
428    }
429
430    #[inline(always)]
431    unsafe fn copy_into_slice_t<T>(&mut self, dst: &mut [MaybeUninit<T>]) -> ReadResult<()> {
432        unsafe { (*self).copy_into_slice_t(dst) }
433    }
434}
435
436#[derive(Error, Debug)]
437pub enum WriteError {
438    #[error("Attempting to write {0} bytes")]
439    WriteSizeLimit(usize),
440    #[cfg(feature = "std")]
441    #[error(transparent)]
442    Io(#[from] std::io::Error),
443}
444
445#[cold]
446const fn write_size_limit(len: usize) -> WriteError {
447    WriteError::WriteSizeLimit(len)
448}
449
450pub type WriteResult<T> = core::result::Result<T, WriteError>;
451
452/// Trait for structured writing of bytes into a source of potentially uninitialized memory.
453pub trait Writer {
454    /// Get a mutable reference to the [`Writer`].
455    ///
456    /// Useful in situations where one has an `impl Writer` that
457    /// needs to be passed to mulitple functions requiring `impl Writer`.
458    ///
459    /// Always prefer this over `&mut writer` to avoid recursive borrows.
460    ///
461    /// ```
462    /// # use wincode::{io::Writer, WriteResult, config::Config, SchemaWrite};
463    /// # use core::mem::MaybeUninit;
464    /// struct FooBar {
465    ///     foo: u32,
466    ///     bar: u32,
467    /// }
468    ///
469    /// unsafe impl<C: Config> SchemaWrite<C> for FooBar {
470    ///     type Src = Self;
471    /// #
472    /// #    fn size_of(src: &Self::Src) -> WriteResult<usize> {
473    /// #        let foo = <u32 as SchemaWrite<C>>::size_of(&src.foo)?;
474    /// #        let bar = <u32 as SchemaWrite<C>>::size_of(&src.bar)?;
475    /// #        Ok(foo + bar)
476    /// #    }
477    ///
478    ///     fn write(mut writer: impl Writer, src: &Self::Src) -> WriteResult<()> {
479    ///         // `writer.by_ref()`; Good ✅
480    ///         let foo = <u32 as SchemaWrite<C>>::write(writer.by_ref(), &src.foo)?;
481    ///         let bar = <u32 as SchemaWrite<C>>::write(writer, &src.bar)?;
482    ///         Ok(())
483    ///     }
484    /// }
485    /// ```
486    #[inline(always)]
487    fn by_ref(&mut self) -> impl Writer {
488        self
489    }
490
491    /// Finalize the writer by performing any required cleanup or flushing.
492    ///
493    /// # Regarding trusted writers
494    ///
495    /// Trusted writers are not guaranteed to live as long as the parent [`Writer`] that
496    /// created them, and are typically short-lived. wincode will call `finish` after
497    /// trusted writers have completed their work, so they may rely on `finish` perform
498    /// local cleanup when needed. Importantly, trusted writers must not perform actions
499    /// that would invalidate the parent [`Writer`].
500    ///
501    /// For example, a file writer may buffer internally and delegate to trusted
502    /// sub-writers with their own buffers. These trusted writers should not close
503    /// the underlying file descriptor or other parent-owned resources, as that would
504    /// invalidate the parent writer.
505    fn finish(&mut self) -> WriteResult<()> {
506        Ok(())
507    }
508
509    /// Write exactly `src.len()` bytes from the given `src` into the writer.
510    fn write(&mut self, src: &[u8]) -> WriteResult<()>;
511
512    /// Advance the parent by `n_bytes` and return a [`Writer`] that can elide bounds checks within
513    /// that `n_bytes` window.
514    ///
515    /// Implementors must:
516    /// - Ensure that either at least `n_bytes` bytes are available backing the
517    ///   returned writer, or return an error.
518    /// - Arrange that the returned `Trusted` writer's methods operate within
519    ///   that `n_bytes` window (it may buffer or prefetch arbitrarily).
520    ///
521    /// Note:
522    /// - `as_trusted_for` is intended for callers that know they will operate
523    ///   within an exact-size window and want to avoid intermediate bounds checks.
524    ///
525    /// # Safety
526    ///
527    /// The caller must treat the returned writer as having exclusive access to
528    /// exactly `n_bytes` bytes of **uninitialized** output space in the parent,
529    /// and must:
530    ///
531    /// - Ensure that no write performed through the `Trusted` writer can
532    ///   address memory outside of that `n_bytes` window.
533    /// - In case the caller does not return an error, ensure that, before the
534    ///   `Trusted` writer is finished or the parent writer is used again,
535    ///   **every byte** in that `n_bytes` window has been initialized at least
536    ///   once via the `Trusted` writer.
537    /// - In case the caller does not return an error, call [`Writer::finish`]
538    ///   on the `Trusted` writer when writing is complete and before the parent
539    ///   writer is used again.
540    ///
541    /// Concretely:
542    /// - All writes performed via the `Trusted` writer (`write`, `write_t`,
543    ///   `write_slice_t`, etc.) must stay within the `[0, n_bytes)` region of
544    ///   the reserved space.
545    /// - It is permitted to overwrite the same bytes multiple times, but if the
546    ///   caller returns no error, the union of all bytes written must cover the
547    ///   entire `[0, n_bytes)` window.
548    ///
549    /// Violating this is undefined behavior, because:
550    /// - `Trusted` writers are permitted to elide bounds checks within the
551    ///   `n_bytes` window; writing past the window may write past the end of
552    ///   the underlying destination.
553    /// - Failing to initialize all `n_bytes` without returning an error may
554    ///   leave uninitialized memory in the destination that later safe code
555    ///   assumes to be fully initialized.
556    #[expect(unused_variables)]
557    #[inline(always)]
558    unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<impl Writer> {
559        /// Default trusted [`Writer`] wrapper used when an implementation does
560        /// not provide a specialized [`Writer::as_trusted_for`].
561        ///
562        /// This wrapper intentionally does not implement [`Writer::finish`].
563        /// The documentation for [`Writer::finish`] and the safety contract of
564        /// [`Writer::as_trusted_for`] tell callers to call `finish` on trusted
565        /// writers before using the parent writer again. Returning `Ok(self)`
566        /// directly would make the trusted writer identical to the parent
567        /// writer, so those callers would end up calling `finish` on the parent
568        /// before they are done using it.
569        ///
570        /// Keeping `finish` on the wrapper as a no-op preserves the expectation
571        /// that trusted writers are finalized after use without forcing an early
572        /// `finish` call on the underlying parent writer.
573        struct TrustedDefault<'a, W: ?Sized> {
574            inner: &'a mut W,
575        }
576
577        impl<W: Writer + ?Sized> Writer for TrustedDefault<'_, W> {
578            #[inline(always)]
579            fn write(&mut self, src: &[u8]) -> WriteResult<()> {
580                self.inner.write(src)
581            }
582
583            #[inline(always)]
584            unsafe fn write_slice_t<T>(&mut self, src: &[T]) -> WriteResult<()> {
585                unsafe { self.inner.write_slice_t(src) }
586            }
587
588            #[inline(always)]
589            unsafe fn write_t<T: ?Sized>(&mut self, src: &T) -> WriteResult<()> {
590                unsafe { self.inner.write_t(src) }
591            }
592
593            #[inline(always)]
594            fn by_ref(&mut self) -> impl Writer {
595                TrustedDefault { inner: self.inner }
596            }
597
598            #[inline(always)]
599            unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<impl Writer> {
600                Ok(TrustedDefault { inner: self.inner })
601            }
602
603            #[inline(always)]
604            fn finish(&mut self) -> WriteResult<()> {
605                Ok(())
606            }
607        }
608
609        Ok(TrustedDefault { inner: self })
610    }
611
612    /// Write `T` as bytes into the source.
613    ///
614    /// # Safety
615    ///
616    /// - `T` must be plain ol' data.
617    #[inline]
618    unsafe fn write_t<T: ?Sized>(&mut self, src: &T) -> WriteResult<()> {
619        let src = unsafe { from_raw_parts((src as *const T).cast::<u8>(), size_of_val(src)) };
620        self.write(src)?;
621        Ok(())
622    }
623
624    /// Write `[T]` as bytes into the source.
625    ///
626    /// # Safety
627    ///
628    /// - `T` must be plain ol' data.
629    #[inline]
630    unsafe fn write_slice_t<T>(&mut self, src: &[T]) -> WriteResult<()> {
631        let len = size_of_val(src);
632        let src = unsafe { from_raw_parts(src.as_ptr().cast::<u8>(), len) };
633        self.write(src)?;
634        Ok(())
635    }
636}
637
638impl<W: Writer + ?Sized> Writer for &mut W {
639    #[inline(always)]
640    fn by_ref(&mut self) -> impl Writer {
641        &mut **self
642    }
643
644    #[inline(always)]
645    fn finish(&mut self) -> WriteResult<()> {
646        (*self).finish()
647    }
648
649    #[inline(always)]
650    fn write(&mut self, src: &[u8]) -> WriteResult<()> {
651        (*self).write(src)
652    }
653
654    #[inline(always)]
655    unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<impl Writer> {
656        unsafe { (*self).as_trusted_for(n_bytes) }
657    }
658
659    #[inline(always)]
660    unsafe fn write_t<T: ?Sized>(&mut self, src: &T) -> WriteResult<()> {
661        unsafe { (*self).write_t(src) }
662    }
663
664    #[inline(always)]
665    unsafe fn write_slice_t<T>(&mut self, src: &[T]) -> WriteResult<()> {
666        unsafe { (*self).write_slice_t(src) }
667    }
668}
669
670mod cursor;
671pub mod slice;
672#[cfg(feature = "std")]
673pub mod std_read;
674#[cfg(feature = "std")]
675pub mod std_write;
676#[cfg(feature = "alloc")]
677mod vec;
678pub use cursor::Cursor;
679#[cfg(test)]
680pub(crate) mod test_util;