arraydeque icon indicating copy to clipboard operation
arraydeque copied to clipboard

Expose `set_len`?

Open NightEule5 opened this issue 2 years ago • 2 comments

I'm writing some embedded code using this crate to buffer USB data. To read data, I have to call a read_packet(&mut [u8]) method, but accessing an ArrayDeque's backing array directly then setting the length is currently impossible.

I could create an array, read into it, then extend, but I'd prefer to use the deque rather than allocating memory for every packet:

let mut usb = ...;
let mut buf = ArrayDeque::<_, 128>::default();

const PKT_SIZE: usize = 64;
assert!(buf.capacity() - buf.len() >= PKT_SIZE);

let mut packet = [0; PKT_SIZE];
let read_count = usb.read_packet(&mut packet)?;
buf.extend_back(packet[..read_count].iter().copied());

If I know a whole packet can fit at the deque's tail, say it's empty and contiguous, I should be able to read into the buffer like this safely:

buf.linearize();
assert!(buf.is_empty());

unsafe {
    let slice = MaybeUninit::slice_assume_init_mut(buf.as_uninit_slice_mut());
    let read_count = usb.read_packet(&mut slice[..PKT_SIZE])?;
    // set_len?
}

But now how do I "grow" the deque to inform it of the new elements? Exposing set_len as is (unsafe) would help in this use case

NightEule5 avatar Oct 11 '23 03:10 NightEule5

An admittedly janky but non-allocating workaround:

use std::iter;

fn reserve<T: Clone + Default, const N: usize>(
    buf: &mut ArrayDeque<T, N>,
    mut additional: usize
) -> (&mut [T], &mut [T]) {
    additional = min(additional, N - buf.len());
    let (front, back) = buf.as_slices();
    let front_len = front.len();
    let back_len = back.len();

    buf.extend_back(iter::repeat(T::default()));

    let (front, back) = buf.as_mut_slices();
    (&mut front[front_len..], &mut back[back_len..])
}

NightEule5 avatar Oct 12 '23 00:10 NightEule5

The functionality appears to closely resemble rtrb's write_chunk_uninit. If you're interested, we welcome your pull request.

andylokandy avatar Nov 17 '23 19:11 andylokandy