evobench_tools/io_utils/
read_buf.rs

1use std::io::Read;
2
3/// Read a buffer of `BUF_SIZE` (the resulting Vec can be smaller);
4/// `left_over` is copied into the buffer at the start, then the
5/// remainder is attempted to be filled from `input`. Returns None if
6/// eof was reached (nothing could be read) and `left_over` is empty.
7/// Panics if `left_over.len() >= `BUF_SIZE`.
8pub fn read_buf<const BUF_SIZE: usize>(
9    left_over: &[u8],
10    input: &mut impl Read,
11) -> std::io::Result<Option<Vec<u8>>> {
12    if left_over.len() >= BUF_SIZE {
13        panic!("`left_over_` must be shorter than `BUF_SIZE`")
14    }
15    let mut buf = Vec::with_capacity(BUF_SIZE);
16    buf.extend_from_slice(left_over);
17    unsafe {
18        // Safe because we're truncating back to the number of bytes
19        // overwritten.
20        buf.set_len(BUF_SIZE)
21    }
22    let n = input.read(&mut buf[left_over.len()..])?;
23    if n == 0 {
24        Ok(None)
25    } else {
26        let num_bytes_overwritten = left_over.len() + n;
27        assert!(num_bytes_overwritten <= BUF_SIZE); // but set_len checks that anyway
28        unsafe {
29            // Safe because this is the range of bytes that were
30            // overwritten, hence not undefined data
31            buf.set_len(num_bytes_overwritten);
32        }
33        Ok(Some(buf))
34    }
35}