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}