我正在尝试用 nom 编写一个 HTTP2 解析器。我正在实现 HPACK 标头压缩,但无法理解如何使用 nom 中的位字段。
例如,Indexed Header Field Representation从第一位为 1 开始。
fn indexed_header_field_tag(i: &[u8]) -> IResult<&[u8], ()> {
nom::bits::streaming::tag(1, 1)(i)
}
这给了我一个我不太明白的编译器警告(老实说,我在 nom 的类型上遇到了一些问题):
error[E0308]: mismatched types
--> src/parser.rs:179:41
|
179 | nom::bits::streaming::tag(1, 1)(i)
| ^ expected tuple, found `&[u8]`
|
= note: expected tuple `(_, usize)`
found reference `&[u8]`
我应该在这里放什么?
另一个例子是:
fn take_2_bits(input: &[u8]) -> IResult<&[u8], u64> {
nom::bits::bits(nom::bits::streaming::take::<_, _, _, (_, _)>(2usize))(input)
}
在这里,我的问题是第一个字节的剩余位被丢弃,即使我想进一步处理它们。
我想我可以使用按位与手动进行操作,但使用 nom 会更好。
我尝试过以下方法,但这给了我很多编译器警告:
fn check_tag(input: &[u8]) -> IResult<&[u8], ()> {
use nom::bits::{bits, bytes, complete::take_bits, complete::tag};
let converted_bits = bits(take_bits(2usize))(2)?;
let something = tag(0x80, 2)(converted_bits);
nom::bits::bytes(something)
}
(灵感来自https://docs.rs/nom/5.1.2/nom/bits/fn.bytes.html)。
它告诉我,没有complete::take_bits
(我猜只有文档有点偏离),但它也告诉我:
368 | let converted_bits = bits(take_bits(2usize))(2)?;
| ^ the trait `nom::traits::Slice<std::ops::RangeFrom<usize>>` is not implemented for `{integer}`
和其他错误,但这只是由于第一个错误而导致的。