swap_buffer_queue/
write.rs

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