swap_buffer_queue/write/
array.rs

1use core::ops::Range;
2
3use crate::{
4    buffer::{Buffer, InsertIntoBuffer},
5    loom::{cell::Cell, LoomUnsafeCell},
6    utils::ArrayWithHeaderAndTrailer,
7    write::{BytesSlice, WriteBytesSlice},
8};
9
10/// A `N`-bytes buffer with a `HEADER_SIZE`-bytes header and a `TRAILER_SIZE`-bytes trailer.
11///
12/// The total size of the buffer is `N + HEADER_SIZE + TRAILER_SIZE`. This buffer is *no_std*.
13#[derive(Default)]
14pub struct WriteArrayBuffer<
15    const N: usize,
16    const HEADER_SIZE: usize = 0,
17    const TRAILER_SIZE: usize = 0,
18>(ArrayWithHeaderAndTrailer<Cell<u8>, HEADER_SIZE, N, TRAILER_SIZE>);
19
20// SAFETY: Buffer values are `Copy` and already initialized
21unsafe impl<const N: usize, const HEADER_SIZE: usize, const TRAILER_SIZE: usize> Buffer
22    for WriteArrayBuffer<N, HEADER_SIZE, TRAILER_SIZE>
23{
24    type Slice<'a> = BytesSlice<'a, HEADER_SIZE, TRAILER_SIZE>;
25
26    #[inline]
27    fn capacity(&self) -> usize {
28        N
29    }
30
31    #[inline]
32    unsafe fn slice(&mut self, range: Range<usize>) -> Self::Slice<'_> {
33        // SAFETY: [Cell<u8>] has the same layout as [u8]
34        BytesSlice::new(unsafe {
35            &mut *(&mut self.0[range.start..HEADER_SIZE + range.end + TRAILER_SIZE] as *mut _
36                as *mut [u8])
37        })
38    }
39
40    #[inline]
41    unsafe fn clear(&mut self, _range: Range<usize>) {}
42}
43
44// SAFETY: Buffer values are `Copy` and already initialized
45unsafe impl<T, const N: usize, const HEADER_SIZE: usize, const TRAILER_SIZE: usize>
46    InsertIntoBuffer<WriteArrayBuffer<N, HEADER_SIZE, TRAILER_SIZE>> for T
47where
48    T: WriteBytesSlice,
49{
50    fn size(&self) -> usize {
51        WriteBytesSlice::size(self)
52    }
53
54    unsafe fn insert_into(
55        self,
56        buffer: &WriteArrayBuffer<N, HEADER_SIZE, TRAILER_SIZE>,
57        index: usize,
58    ) {
59        let slice =
60            &buffer.0[HEADER_SIZE + index..HEADER_SIZE + index + WriteBytesSlice::size(&self)];
61        // SAFETY: [Cell<u8>] has the same layout as UnsafeCell<[u8]>
62        unsafe {
63            (*(slice as *const _ as *const LoomUnsafeCell<[u8]>)).with_mut(|s| self.write(&mut *s));
64        };
65    }
66}