I'm trying to write an parser for and a binary format using Nom,
I have limited experience in Rust and wrote some server side code with Axum, etc. but this is time when I couldn't avoid encountering borrow checker (eh..).
There is code I have:
use nom::number::complete::{le_u16, le_u32};
use nom::{combinator::map, sequence::tuple, IResult};
#[derive(Clone, Debug)]
pub struct BinaryFormat<'bfmt> {
binary_data: &'bfmt [u8],
}
impl<'bfmt> BinaryFormat<'bfmt> {
pub fn new(binary_data: &'bfmt [u8]) -> Self {
Self { binary_data }
}
pub fn parse(&self) -> IResult<&[u8], ()> {
let (_, header) = parse_chunk_header(self.binary_data)?;
println!("header: {:?}", header);
// TODO: continue parsing
Ok((self.binary_data, ()))
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ChunkHeader {
pub typ: u16,
pub header_size: u16,
pub chunk_size: u32,
}
pub fn parse_chunk_header(input: &[u8]) -> IResult<&[u8], ChunkHeader> {
map(
tuple((le_u16, le_u16, le_u32)),
|(typ, header_size, chunk_size)| ChunkHeader {
typ,
header_size,
chunk_size,
},
)(input)
}
#[cfg(test)]
mod tests {
use super::*;
use anyhow::Result;
#[test]
fn test_parser() -> Result<()> {
let dir_path = std::path::Path::new("data/binaries");
let files = dir_path.read_dir()?;
for file in files {
let file = file?.path().canonicalize()?;
println!("testing {:?}", file);
let file_bytes: Vec<u8> = std::fs::read(&file)?;
let parser = BinaryFormat::new(file_bytes.as_slice());
parser.parse()?;
}
Ok(())
}
}
During running the test, getting this error:
error[E0597]: `file_bytes` does not live long enough
--> src/binary_parser.rs:53:44
|
52 | let file_bytes: Vec<u8> = std::fs::read(&file)?;
| ---------- binding `file_bytes` declared here
53 | let parser = BinaryFormat::new(file_bytes.as_slice());
| ------------------^^^^^^^^^^^^^^^^^^^^^-
| | |
| | borrowed value does not live long enough
| argument requires that `file_bytes` is borrowed for `'static`
54 | parser.parse()?;
55 | }
| - `file_bytes` dropped here while still borrowed
error[E0597]: `parser` does not live long enough
--> src/binary_parser.rs:54:13
|
53 | let parser = BinaryFormat::new(file_bytes.as_slice());
| ------ binding `parser` declared here
54 | parser.parse()?;
| ^^^^^^^^^^^^^^
| |
| borrowed value does not live long enough
| argument requires that `parser` is borrowed for `'static`
55 | }
| - `parser` dropped here while still borrowed
I had borrow checker problem within the code but managed to fixed it but now same in the test.
How can I better structure the code for my case?
Any guidance would be greatly appreciated!