2

我正在尝试解析包含一些压缩格式数据的格式。如何将解压缩的部分作为常规解析的一部分进行解析?目前我遇到了借用检查器的问题,因为错误部分nom希望compressed_data在从返回时引用该部分parse_header,这将超出范围。

#[macro_use]
use nom::combinator::map_res;
use nom::number::complete::le_u32;
use nom::IResult;
use nom::bytes::complete::take;
use std::io::prelude::*;
use std::io;
use flate2::bufread::DeflateDecoder;

#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Replay {
  header_length: u32
, header: Header
}

#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Header {
  version: String
}

fn decode_reader(bytes: &[u8]) -> io::Result<Vec<u8>> {
   let mut deflater = DeflateDecoder::new(&bytes[..]);
   let mut s = Vec::new();
   deflater.read(&mut s)?;
   Ok(s)
}

pub fn parse_header(input: &[u8]) -> IResult<&[u8],Header> {
  let (input, version) = map_res(take(8u8), std::str::from_utf8)(input)?;
  Ok((input, Header { version: version.to_string() }))
}

pub fn parse_replay(input: &[u8]) -> IResult<&[u8],Replay> {
  let (input, header_length) = le_u32(input)?;
  let (input, _) = le_u32(input)?;
  let (input, compressed_data) = map_res(take(header_length), decode_reader)(input)?;
  let compressed_ary: &[_] = &compressed_data;
  let (com_input, header) = parse_header(compressed_ary)?;
  
  Ok((input, Replay { header_length, header }))
}
cannot return value referencing local variable `compressed_data`

returns a value referencing data owned by the current function
rustc(E0515)
4

1 回答 1

0

Not sure if you've already solved this, but the issue is caused by the use of ? in parse_header(compressed_ary)? which will, on error, return a nom::Err(nom::error::Error<&[u8]>) that references data owned by the compressed_data variable. You could use .unwrap() but you'd probably want to map the error into something that references input instead of compressed_data, but this will likely mean matching on nom::Err and mapping each of the 3 variants of nom::Err to their equivalent, but with a substituted reference to input. You could also just return a specific nom error rather than mapping each enum variant if you don't expect to the Incomplete or Failure cases

于 2021-04-27T06:28:58.317 回答