1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
//! [`Buffer`](`crate::buffer::Buffer`) implementations to be used with
//! [`Write::write`](std::io::Write::write).
//!
//! [`WriteArrayBuffer`] and [`WriteVecBuffer`] are well suited when there are objects to be
//! serialized with a known-serialization size. Indeed, objects can then be serialized directly on
//! the queue's buffer, avoiding allocation.
//!
//! # Examples
//! ```rust
//! # use std::io::Write;
//! # use swap_buffer_queue::{Queue, write::{WriteBytesSlice, WriteVecBuffer}};
//! // Creates a WriteVecBuffer queue with a 2-bytes header
//! let queue: Queue<WriteVecBuffer<2>> = Queue::with_capacity((1 << 16) - 1);
//! queue
//! .try_enqueue((256, |slice: &mut [u8]| { /* write the slice */ }))
//! .unwrap();
//! queue
//! .try_enqueue((42, |slice: &mut [u8]| { /* write the slice */ }))
//! .unwrap();
//! let mut slice = queue.try_dequeue().unwrap();
//! // Adds a header with the len of the buffer
//! let len = (slice.len() as u16).to_be_bytes();
//! slice.header().copy_from_slice(&len);
//! // Let's pretend we have a writer
//! let mut writer: Vec<u8> = Default::default();
//! assert_eq!(writer.write(slice.frame()).unwrap(), 300);
//! ```
use std::ops::{Deref, DerefMut};
mod array;
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
mod vec;
pub use array::WriteArrayBuffer;
#[cfg(feature = "std")]
pub use vec::WriteVecBuffer;
/// A bytes slice with a `HEADER_SIZE`-bytes header and a `TRAILER_SIZE`-bytes trailer.
///
/// It implements [`Deref`] and [`DerefMut`], targeting the *unframed* part of the slice,
/// without the header and the trailer. The complete slice (with header and trailer) can be
/// retrieved using [`frame`](BytesSlice::frame) or [`frame_mut`](BytesSlice::frame_mut) methods.
///
/// # Examples
///
/// ```rust
/// # use std::ops::Deref;
/// # use swap_buffer_queue::buffer::BufferSlice;
/// # use swap_buffer_queue::Queue;
/// # use swap_buffer_queue::write::{BytesSlice, WriteBytesSlice, WriteVecBuffer};
/// # let queue: Queue<WriteVecBuffer<2, 4>> = Queue::with_capacity(42);
/// # queue.try_enqueue(&[2u8, 3, 4, 5] as &[_]).unwrap();
/// let mut slice: BufferSlice<WriteVecBuffer<2, 4>, _> /* = ... */;
/// # slice = queue.try_dequeue().unwrap();
/// assert_eq!(slice.deref().deref(), &[2, 3, 4, 5]);
/// slice.header().copy_from_slice(&[0, 1]);
/// slice.trailer().copy_from_slice(&[6, 7, 8, 9]);
/// assert_eq!(slice.frame(), &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
/// ```
#[derive(Debug)]
pub struct BytesSlice<'a, const HEADER_SIZE: usize = 0, const TRAILER_SIZE: usize = 0>(
pub(crate) &'a mut [u8],
);
impl<'a, const HEADER_SIZE: usize, const TRAILER_SIZE: usize>
BytesSlice<'a, HEADER_SIZE, TRAILER_SIZE>
{
#[inline]
pub(crate) fn new(slice: &'a mut [u8]) -> Self {
Self(slice)
}
/// Returns a mutable reference on the header part of the slice
/// (see [examples](BytesSlice#examples)).
#[inline]
pub fn header(&mut self) -> &mut [u8] {
&mut self.0[..HEADER_SIZE]
}
/// Returns a mutable reference on the trailer part of the slice
/// (see [examples](BytesSlice#examples)).
#[inline]
pub fn trailer(&mut self) -> &mut [u8] {
let len = self.0.len();
&mut self.0[len - TRAILER_SIZE..]
}
/// Returns the complete frame slice, with header and trailer
/// (see [examples](BytesSlice#examples)).
#[inline]
pub fn frame(&self) -> &[u8] {
self.0
}
/// Returns the complete mutable frame slice, with header and trailer
/// (see [examples](BytesSlice#examples)).
#[inline]
pub fn frame_mut(&mut self) -> &mut [u8] {
self.0
}
}
impl<const HEADER_SIZE: usize, const TRAILER_SIZE: usize> Deref
for BytesSlice<'_, HEADER_SIZE, TRAILER_SIZE>
{
type Target = [u8];
#[inline]
fn deref(&self) -> &Self::Target {
&self.0[HEADER_SIZE..self.0.len() - TRAILER_SIZE]
}
}
impl<const HEADER_SIZE: usize, const TRAILER_SIZE: usize> DerefMut
for BytesSlice<'_, HEADER_SIZE, TRAILER_SIZE>
{
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
let len = self.0.len();
&mut self.0[HEADER_SIZE..len - TRAILER_SIZE]
}
}
/// Bytes slice writer, used by [`WriteArrayBuffer`] and [`WriteVecBuffer`].
pub trait WriteBytesSlice {
/// Returns the size of the slice to be written.
fn size(&self) -> usize;
/// Writes the slice.
fn write(self, slice: &mut [u8]);
}
impl WriteBytesSlice for &[u8] {
#[inline]
fn size(&self) -> usize {
self.len()
}
#[inline]
fn write(self, slice: &mut [u8]) {
slice.copy_from_slice(self.as_ref());
}
}
impl<F> WriteBytesSlice for (usize, F)
where
F: FnOnce(&mut [u8]),
{
#[inline]
fn size(&self) -> usize {
self.0
}
#[inline]
fn write(self, slice: &mut [u8]) {
self.1(slice);
}
}