So, I would like to read()
some data from a TcpStream
and append it a Vec<u8>
.
Of course, I could simply read()
into a separate [u8]
first, and then use extend_from_slice()
to append the data to the vector. But I think this would cause an unnecessary copy of the data!
It would be way better (more efficient) to read into the vector directly.
One option would be to grow the Vec<u8>
, by using resize()
, in order to have some "extra" space at the end, which we then can pass to read()
, as an &mut [u8]
slice. This works okay.
Unfortunately, the resize()
function must initialize the "extra" space of the vector to a specific value, even though we are going to overwrite that area immediately. This seems wasteful!
Another option would be to use reserve()
and spare_capacity_mut()
. Unfortunately, the latter gives me an MaybeUninit<u8>
, whereas TcpStream::read()
needs an &mut [u8]
slice...
Is there any way to read()
directly into a MaybeUninit<u8>
???
Best workaround to grow the vector without initializing the "extra" space that I came up with is:
fn grow_buffer(buffer: &mut Vec<u8>, new_length: usize) {
if new_length > buffer.capacity() {
buffer.reserve(new_length - buffer.len());
}
unsafe { buffer.set_len(new_length); }
}
But it requires unsafe
, which I would like to avoid
(even though I think that, in this specific case, above code should be "safe")