Skip to main content

Writer

Trait Writer 

Source
pub trait Writer {
    // Required method
    fn write(&mut self, src: &[u8]) -> WriteResult<()>;

    // Provided methods
    fn by_ref(&mut self) -> impl Writer { ... }
    fn finish(&mut self) -> WriteResult<()> { ... }
    unsafe fn as_trusted_for(
        &mut self,
        n_bytes: usize,
    ) -> WriteResult<impl Writer> { ... }
    unsafe fn write_t<T: ?Sized>(&mut self, src: &T) -> WriteResult<()> { ... }
    unsafe fn write_slice_t<T>(&mut self, src: &[T]) -> WriteResult<()> { ... }
}
Expand description

Trait for structured writing of bytes into a source of potentially uninitialized memory.

Required Methods§

Source

fn write(&mut self, src: &[u8]) -> WriteResult<()>

Write exactly src.len() bytes from the given src into the writer.

Provided Methods§

Source

fn by_ref(&mut self) -> impl Writer

Get a mutable reference to the Writer.

Useful in situations where one has an impl Writer that needs to be passed to mulitple functions requiring impl Writer.

Always prefer this over &mut writer to avoid recursive borrows.

struct FooBar {
    foo: u32,
    bar: u32,
}

unsafe impl<C: Config> SchemaWrite<C> for FooBar {
    type Src = Self;

    fn write(mut writer: impl Writer, src: &Self::Src) -> WriteResult<()> {
        // `writer.by_ref()`; Good ✅
        let foo = <u32 as SchemaWrite<C>>::write(writer.by_ref(), &src.foo)?;
        let bar = <u32 as SchemaWrite<C>>::write(writer, &src.bar)?;
        Ok(())
    }
}
Source

fn finish(&mut self) -> WriteResult<()>

Finalize the writer by performing any required cleanup or flushing.

§Regarding trusted writers

Trusted writers are not guaranteed to live as long as the parent Writer that created them, and are typically short-lived. wincode will call finish after trusted writers have completed their work, so they may rely on finish perform local cleanup when needed. Importantly, trusted writers must not perform actions that would invalidate the parent Writer.

For example, a file writer may buffer internally and delegate to trusted sub-writers with their own buffers. These trusted writers should not close the underlying file descriptor or other parent-owned resources, as that would invalidate the parent writer.

Source

unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<impl Writer>

Advance the parent by n_bytes and return a Writer that can elide bounds checks within that n_bytes window.

Implementors must:

  • Ensure that either at least n_bytes bytes are available backing the returned writer, or return an error.
  • Arrange that the returned Trusted writer’s methods operate within that n_bytes window (it may buffer or prefetch arbitrarily).

Note:

  • as_trusted_for is intended for callers that know they will operate within an exact-size window and want to avoid intermediate bounds checks.
§Safety

The caller must treat the returned writer as having exclusive access to exactly n_bytes bytes of uninitialized output space in the parent, and must:

  • Ensure that no write performed through the Trusted writer can address memory outside of that n_bytes window.
  • In case the caller does not return an error, ensure that, before the Trusted writer is finished or the parent writer is used again, every byte in that n_bytes window has been initialized at least once via the Trusted writer.
  • In case the caller does not return an error, call Writer::finish on the Trusted writer when writing is complete and before the parent writer is used again.

Concretely:

  • All writes performed via the Trusted writer (write, write_t, write_slice_t, etc.) must stay within the [0, n_bytes) region of the reserved space.
  • It is permitted to overwrite the same bytes multiple times, but if the caller returns no error, the union of all bytes written must cover the entire [0, n_bytes) window.

Violating this is undefined behavior, because:

  • Trusted writers are permitted to elide bounds checks within the n_bytes window; writing past the window may write past the end of the underlying destination.
  • Failing to initialize all n_bytes without returning an error may leave uninitialized memory in the destination that later safe code assumes to be fully initialized.
Source

unsafe fn write_t<T: ?Sized>(&mut self, src: &T) -> WriteResult<()>

Write T as bytes into the source.

§Safety
  • T must be plain ol’ data.
Source

unsafe fn write_slice_t<T>(&mut self, src: &[T]) -> WriteResult<()>

Write [T] as bytes into the source.

§Safety
  • T must be plain ol’ data.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

impl Writer for &mut [MaybeUninit<u8>]

Source§

unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<impl Writer>

Source§

fn write(&mut self, src: &[u8]) -> WriteResult<()>

Source§

impl Writer for &mut [u8]

Source§

unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<impl Writer>

Source§

fn write(&mut self, src: &[u8]) -> WriteResult<()>

Source§

impl Writer for Cursor<&mut Vec<u8>>

Source§

fn write(&mut self, src: &[u8]) -> WriteResult<()>

Source§

fn finish(&mut self) -> WriteResult<()>

Source§

unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<impl Writer>

Source§

impl Writer for Cursor<&mut [u8]>

Source§

fn write(&mut self, src: &[u8]) -> WriteResult<()>

Source§

fn finish(&mut self) -> WriteResult<()>

Source§

unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<impl Writer>

Source§

impl Writer for Cursor<Box<[u8]>>

Source§

fn write(&mut self, src: &[u8]) -> WriteResult<()>

Source§

fn finish(&mut self) -> WriteResult<()>

Source§

unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<impl Writer>

Source§

impl Writer for Cursor<Vec<u8>>

Source§

fn write(&mut self, src: &[u8]) -> WriteResult<()>

Source§

fn finish(&mut self) -> WriteResult<()>

Source§

unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<impl Writer>

Source§

impl Writer for Vec<u8>

Writer implementation for Vec<u8> that appends to the vector. The vector will grow as needed.

§Examples

Writing to a new vector.

let mut vec = Vec::new();
let bytes = [1, 2, 3];
vec.write(&bytes).unwrap();
assert_eq!(vec, &[1, 2, 3]);

Writing to an existing vector.

let mut vec = vec![1, 2, 3];
let bytes = [4, 5, 6];
vec.write(&bytes).unwrap();
assert_eq!(vec, &[1, 2, 3, 4, 5, 6]);
Source§

fn write(&mut self, src: &[u8]) -> WriteResult<()>

Source§

unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<impl Writer>

Source§

impl<W: Write + ?Sized> Writer for BufWriter<W>

Source§

fn write(&mut self, src: &[u8]) -> WriteResult<()>

Source§

fn finish(&mut self) -> WriteResult<()>

Source§

impl<W: Writer + ?Sized> Writer for &mut W

Source§

fn by_ref(&mut self) -> impl Writer

Source§

fn finish(&mut self) -> WriteResult<()>

Source§

fn write(&mut self, src: &[u8]) -> WriteResult<()>

Source§

unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<impl Writer>

Source§

unsafe fn write_t<T: ?Sized>(&mut self, src: &T) -> WriteResult<()>

Source§

unsafe fn write_slice_t<T>(&mut self, src: &[T]) -> WriteResult<()>

Source§

impl<const N: usize> Writer for Cursor<[u8; N]>

Source§

fn write(&mut self, src: &[u8]) -> WriteResult<()>

Source§

fn finish(&mut self) -> WriteResult<()>

Source§

unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<impl Writer>

Implementors§

Source§

impl Writer for wincode::io::Cursor<&mut Vec<u8>>

Available on crate feature alloc only.

Writer implementation for &mut Vec<u8> that overwrites the underlying vector’s memory. The vector will grow as needed.

§Examples

Overwriting an existing vector.

let mut vec = vec![0; 3];
let mut cursor = Cursor::new(&mut vec);
let bytes = [1, 2, 3, 4];
cursor.write(&bytes).unwrap();
assert_eq!(&vec, &[1, 2, 3, 4]);

Growing a vector.

let mut vec = vec![];
let mut cursor = Cursor::new(&mut vec);
let bytes = [1, 2, 3];
cursor.write(&bytes).unwrap();
assert_eq!(&vec, &[1, 2, 3]);
Source§

impl Writer for wincode::io::Cursor<&mut [MaybeUninit<u8>]>

Source§

impl Writer for wincode::io::Cursor<&mut [u8]>

Source§

impl Writer for wincode::io::Cursor<Vec<u8>>

Available on crate feature alloc only.

Writer implementation for Vec<u8> that overwrites the underlying vector’s memory. The vector will grow as needed.

§Examples

Overwriting an existing vector.

let mut cursor = Cursor::new(vec![0; 3]);
let bytes = [1, 2, 3, 4];
cursor.write(&bytes).unwrap();
assert_eq!(cursor.into_inner(), &[1, 2, 3, 4]);

Growing a vector.

let mut cursor = Cursor::new(vec![]);
let bytes = [1, 2, 3];
cursor.write(&bytes).unwrap();
assert_eq!(cursor.into_inner(), &[1, 2, 3]);
Source§

impl Writer for SliceMutUnchecked<'_, MaybeUninit<u8>>

Source§

impl Writer for SliceMutUnchecked<'_, u8>

Source§

impl<W: Write + ?Sized> Writer for WriteAdapter<W>

Source§

impl<const N: usize> Writer for wincode::io::Cursor<&mut MaybeUninit<[u8; N]>>