Obtaining a slice from `Read` instead of filling up a buffer

Hi,

I'm trying to write a zero-copy parser for a binary file format in Rust. I've read the entire file into a Vec<u8> and I'm looking for a function that takes in a usize or something and returns a slice of the Vec with those number of bytes. Sort of like read_exact() but instead of filling up a buffer it returns a slice. Is there any such function in the standard library?

You can just index the vector with a range to do that, no function required: &my_vec[..num_bytes]

Or if you need to start from an offset: &my_vec[start..end]

Bear in mind that end there is exclusive, not inclusive - use ..= instead of .. if you want an inclusive range.

This is what I've been doing till now but it starts to get a bit tedious when I need to take different offsets from the vector at different points and store them into structs. It'll be easier to use something like a Cursor that implements Read.

This isn't quite what you're looking for, but I've used a nice trick of just redefining the slice I'm parsing as I go. I do a lot of this in my latex snippet crate, e.g.

    let mut latex: &str = &latex;
    if let Some(i) = latex.find(r"\section") {
        html_section(fmt, &latex[..i])?;
        latex = &latex[i + r"\section".len()..];
        if latex.chars().next() == Some('*') {
            latex = &latex[1..];
        }
        let title = parse_title(latex);
        latex = &latex[title.len()..];

It feels and is hokey, but it does avoid having to keep adding onto an initial offset.

That is certainly better than what I'm doing right now. Another thing possibly would be to make a trait like:

trait ReadSlice<'a> {
    fn read_slice(&mut self, length: usize) -> &'a [u8];
}

And somehow implement it for Cursor. I'm not sure whether this is idiomatic or even a good idea.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.