在标称5.1.2中使用位解析器时找不到正确的类型参数

问题描述

我无法在nom 5中找到正确的语法来进行位解析。

我正在尝试:

pub fn parse_normal_record_header(i: &[u8]) -> nom::IResult<&[u8],FitRecordHeader> {

     let (i,_) = nom::bits::bits(nom::bits::complete::tag(0x0,1_usize))(i)?;
     ...
}

并从编译器获取此信息:

error[E0283]: type annotations needed
   --> src/fitparsers.rs:658:18
    |
658 |     let (i,1_usize))(i)?;
    |                  ^^^^^^^^^^^^^^^ cannot infer type for type parameter `E1` declared on the function `bits`
    |
   ::: /Users/djk/.cargo/registry/src/github.com-1ecc6299db9ec823/nom-5.1.2/src/bits/mod.rs:37:23
    |
37  | pub fn bits<I,O,E1: ParseError<(I,usize)>+ErrorConvert<E2>,E2: ParseError<I>,P>(parser: P) -> impl Fn(I) -> IResult<I,E2>
    |                       ---------------------- required by this bound in `nom::bits`
    |
    = note: cannot satisfy `_: nom::error::ParseError<(&[u8],usize)>`
help: consider specifying the type arguments in the function call
    |
658 |     let (i,_) = nom::bits::bits::<I,E1,E2,P>(nom::bits::complete::tag(0x0,1_usize))(i)?;

我已经尝试过各种可怕的事情,

let (i,_) = nom::bits::bits(nom::bits::complete::tag::<&[u8],(&[u8],u8),usize,dyn nom::error::ParseError<(&[u8],usize)>>(0,1_usize))(i)?;

...试图遵循我在nom来源中看到的内容,但这会产生不同的错误

error[E0277]: the size for values of type `dyn nom::error::ParseError<(&[u8],usize)>` cannot be kNown at compilation time
   --> src/fitparsers.rs:662:34
    |
662 | ...om::bits::bits(nom::bits::complete::tag::<&[u8],1_usize))(i)?;
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size kNown at compile-time
    |
   ::: /Users/djk/.cargo/registry/src/github.com-1ecc6299db9ec823/nom-5.1.2/src/bits/complete.rs:57:21
    |
57  | pub fn tag<I,C,E: ParseError<(I,usize)>>(pattern: O,count: C) -> impl Fn((I,usize)) -> IResult<(I,usize),E>
    |                     - required by this bound in `nom::complete::tag`
    |
    = help: the trait `std::marker::Sized` is not implemented for `dyn nom::error::ParseError<(&[u8],usize)>`

我在做什么错了?

解决方法

这是一个已知问题。以下注释就足够了:

nom::bits::complete::tag::<_,_,(_,_)>(0x0,1_usize)

但是,请注意,您可能在这里犯了另一个错误。是的,bits组合器将nom切换到位模式,但仅在内部解析器的持续时间内。如果不完整,则在退出时丢弃该字节的剩余部分。因此,bits的正常工作方式是

nom::bits::bits(nom::sequence::tuple::<_,_),_>((
    /* a number of bitfields that add up to a whole number of bytes */
)))(i)?

或类似的东西。内部解析器不必是tuple,但它必须是消耗8位倍数的位级解析器,否则某些位将在退出bits上下文时被丢弃。>