Compare commits

...

2 commits

View file

@ -7,7 +7,7 @@ use std::{
use nom::{ use nom::{
bits::complete as bits, bits::complete as bits,
multi::{many0, many_m_n}, multi::{many0, many_m_n}, error::ParseError, Offset,
}; };
use nom::{combinator::map, sequence::pair}; use nom::{combinator::map, sequence::pair};
use parsers::fold_till; use parsers::fold_till;
@ -15,7 +15,7 @@ use parsers::fold_till;
mod parsers; mod parsers;
type Input<'a> = (&'a [u8], usize); type Input<'a> = (&'a [u8], usize);
type IResult<'a, T> = nom::IResult<Input<'a>, T>; type IResult<'a, T, E> = nom::IResult<Input<'a>, T, E>;
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
struct Packet { struct Packet {
@ -24,7 +24,7 @@ struct Packet {
} }
impl Packet { impl Packet {
pub fn parse(i: Input) -> IResult<Packet> { pub fn parse<'a, E: ParseError<Input<'a>>>(i: Input<'a>) -> IResult<'a, Packet, E> {
map( map(
pair(bits::take(3_usize), PacketType::parse), pair(bits::take(3_usize), PacketType::parse),
|(version, typ)| Packet { version, typ }, |(version, typ)| Packet { version, typ },
@ -52,7 +52,7 @@ enum PacketType {
} }
impl PacketType { impl PacketType {
pub fn parse(i: Input) -> IResult<PacketType> { pub fn parse<'a, E: ParseError<Input<'a>>>(i: Input<'a>) -> IResult<'a, PacketType, E> {
let (i, operator) = map(bits::take(3_usize), |type_id: u8| { let (i, operator) = map(bits::take(3_usize), |type_id: u8| {
Operator::try_from(type_id) Operator::try_from(type_id)
})(i)?; })(i)?;
@ -68,14 +68,14 @@ impl PacketType {
} }
} }
fn parse_sub_packets(i: Input) -> IResult<Vec<Packet>> { fn parse_sub_packets<'a, E: ParseError<Input<'a>>>(i: Input<'a>) -> IResult<'a, Vec<Packet>, E> {
enum LengthType { enum LengthType {
Bits(usize), Bits(usize),
Packets(usize), Packets(usize),
} }
impl LengthType { impl LengthType {
pub fn parse(i: Input) -> IResult<Self> { pub fn parse<'a, E: ParseError<Input<'a>>>(i: Input<'a>) -> IResult<'a, Self, E> {
let (i, length_type_id) = bits::take(1_usize)(i)?; let (i, length_type_id) = bits::take(1_usize)(i)?;
match length_type_id { match length_type_id {
0 => map(bits::take(15_usize), LengthType::Bits)(i), 0 => map(bits::take(15_usize), LengthType::Bits)(i),
@ -99,7 +99,8 @@ impl PacketType {
let (subpackets_end, subpackets) = many0(Packet::parse)(subpackets_input)?; let (subpackets_end, subpackets) = many0(Packet::parse)(subpackets_input)?;
let new_input = (&i.0[new_byte_offset..], new_bit_offset); let new_input = (&i.0[new_byte_offset..], new_bit_offset);
assert_eq!(subpackets_end, new_input); assert_eq!(i.0.offset(subpackets_end.0), i.0.offset(new_input.0));
assert_eq!(subpackets_end.1, new_input.1);
Ok(( Ok((
new_input, new_input,
@ -109,7 +110,7 @@ impl PacketType {
} }
} }
fn parse_literal_value(i: Input) -> IResult<usize> { fn parse_literal_value<'a, E: ParseError<Input<'a>>>(i: Input<'a>) -> IResult<'a, usize, E> {
fold_till( fold_till(
pair(bits::take(1_usize), bits::take(4_usize)), pair(bits::take(1_usize), bits::take(4_usize)),
|| 0, || 0,
@ -198,7 +199,7 @@ fn main() {
.flatten() .flatten()
.collect(); .collect();
let packet = Packet::parse((&bytes, 0)).unwrap().1; let packet = Packet::parse::<nom::error::Error<_>>((&bytes, 0)).unwrap().1;
println!("{}", packet.version_sum()); println!("{}", packet.version_sum());
println!("{}", packet.typ.evaluate()); println!("{}", packet.typ.evaluate());
} }