cu_bincode/enc/write.rs
1//! This module contains writer-based structs and traits.
2//!
3//! Because `std::io::Write` is only limited to `std` and not `core`, we provide our own [Writer].
4
5use crate::error::EncodeError;
6
7/// Trait that indicates that a struct can be used as a destination to encode data too. This is used by [Encode]
8///
9/// [Encode]: ../trait.Encode.html
10pub trait Writer {
11 /// Write `bytes` to the underlying writer. Exactly `bytes.len()` bytes must be written, or else an error should be returned.
12 fn write(&mut self, bytes: &[u8]) -> Result<(), EncodeError>;
13}
14
15impl<T: Writer> Writer for &mut T {
16 #[inline]
17 fn write(&mut self, bytes: &[u8]) -> Result<(), EncodeError> {
18 (**self).write(bytes)
19 }
20}
21
22/// A helper struct that implements `Writer` for a `&[u8]` slice.
23///
24/// ```
25/// # extern crate cu_bincode as bincode;
26/// use bincode::enc::write::{Writer, SliceWriter};
27///
28/// let destination = &mut [0u8; 100];
29/// let mut writer = SliceWriter::new(destination);
30/// writer.write(&[1, 2, 3, 4, 5]).unwrap();
31///
32/// assert_eq!(writer.bytes_written(), 5);
33/// assert_eq!(destination[0..6], [1, 2, 3, 4, 5, 0]);
34/// ```
35pub struct SliceWriter<'storage> {
36 slice: &'storage mut [u8],
37 original_length: usize,
38}
39
40impl<'storage> SliceWriter<'storage> {
41 /// Create a new instance of `SliceWriter` with the given byte array.
42 pub fn new(bytes: &'storage mut [u8]) -> SliceWriter<'storage> {
43 let original = bytes.len();
44 SliceWriter {
45 slice: bytes,
46 original_length: original,
47 }
48 }
49
50 /// Return the amount of bytes written so far.
51 pub fn bytes_written(&self) -> usize {
52 self.original_length - self.slice.len()
53 }
54}
55
56impl Writer for SliceWriter<'_> {
57 #[inline(always)]
58 fn write(&mut self, bytes: &[u8]) -> Result<(), EncodeError> {
59 if bytes.len() > self.slice.len() {
60 return Err(EncodeError::UnexpectedEnd);
61 }
62 let (a, b) = core::mem::take(&mut self.slice).split_at_mut(bytes.len());
63 a.copy_from_slice(bytes);
64 self.slice = b;
65
66 Ok(())
67 }
68}
69
70/// A writer that counts how many bytes were written. This is useful for e.g. pre-allocating buffers bfeore writing to them.
71#[derive(Default)]
72pub struct SizeWriter {
73 /// the amount of bytes that were written so far
74 pub bytes_written: usize,
75}
76impl Writer for SizeWriter {
77 #[inline(always)]
78 fn write(&mut self, bytes: &[u8]) -> Result<(), EncodeError> {
79 self.bytes_written += bytes.len();
80
81 Ok(())
82 }
83}