mirror of https://git.sr.ht/~stygianentity/bincode
83 lines
2.4 KiB
Rust
83 lines
2.4 KiB
Rust
//! This module contains writer-based structs and traits.
|
|
//!
|
|
//! Because `std::io::Write` is only limited to `std` and not `core`, we provide our own [Writer].
|
|
|
|
use crate::error::EncodeError;
|
|
|
|
/// Trait that indicates that a struct can be used as a destination to encode data too. This is used by [Encode]
|
|
///
|
|
/// [Encode]: ../trait.Encode.html
|
|
pub trait Writer {
|
|
/// Write `bytes` to the underlying writer. Exactly `bytes.len()` bytes must be written, or else an error should be returned.
|
|
fn write(&mut self, bytes: &[u8]) -> Result<(), EncodeError>;
|
|
}
|
|
|
|
impl<T: Writer> Writer for &mut T {
|
|
#[inline]
|
|
fn write(&mut self, bytes: &[u8]) -> Result<(), EncodeError> {
|
|
(**self).write(bytes)
|
|
}
|
|
}
|
|
|
|
/// A helper struct that implements `Writer` for a `&[u8]` slice.
|
|
///
|
|
/// ```
|
|
/// use bincode::enc::write::{Writer, SliceWriter};
|
|
///
|
|
/// let destination = &mut [0u8; 100];
|
|
/// let mut writer = SliceWriter::new(destination);
|
|
/// writer.write(&[1, 2, 3, 4, 5]).unwrap();
|
|
///
|
|
/// assert_eq!(writer.bytes_written(), 5);
|
|
/// assert_eq!(destination[0..6], [1, 2, 3, 4, 5, 0]);
|
|
/// ```
|
|
pub struct SliceWriter<'storage> {
|
|
slice: &'storage mut [u8],
|
|
original_length: usize,
|
|
}
|
|
|
|
impl<'storage> SliceWriter<'storage> {
|
|
/// Create a new instance of `SliceWriter` with the given byte array.
|
|
pub fn new(bytes: &'storage mut [u8]) -> SliceWriter<'storage> {
|
|
let original = bytes.len();
|
|
SliceWriter {
|
|
slice: bytes,
|
|
original_length: original,
|
|
}
|
|
}
|
|
|
|
/// Return the amount of bytes written so far.
|
|
pub fn bytes_written(&self) -> usize {
|
|
self.original_length - self.slice.len()
|
|
}
|
|
}
|
|
|
|
impl Writer for SliceWriter<'_> {
|
|
#[inline(always)]
|
|
fn write(&mut self, bytes: &[u8]) -> Result<(), EncodeError> {
|
|
if bytes.len() > self.slice.len() {
|
|
return Err(EncodeError::UnexpectedEnd);
|
|
}
|
|
let (a, b) = core::mem::take(&mut self.slice).split_at_mut(bytes.len());
|
|
a.copy_from_slice(bytes);
|
|
self.slice = b;
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
/// A writer that counts how many bytes were written. This is useful for e.g. pre-allocating buffers before writing to them.
|
|
#[derive(Default)]
|
|
pub struct SizeWriter {
|
|
/// the amount of bytes that were written so far
|
|
pub bytes_written: usize,
|
|
}
|
|
impl Writer for SizeWriter {
|
|
#[inline(always)]
|
|
fn write(&mut self, bytes: &[u8]) -> Result<(), EncodeError> {
|
|
self.bytes_written += bytes.len();
|
|
|
|
Ok(())
|
|
}
|
|
}
|