1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//! # Nom parsers

use std::string::FromUtf8Error;

use nom::{
    combinator::{map, map_res},
    error::{FromExternalError, ParseError},
    multi::length_data,
    number::complete::{le_i32, le_u32},
    IResult, Parser,
};

use crate::crc::CRC;

use super::CRCTreeNode;

/// Parse a CRC node
pub fn parse_crc_node<'r, D, P, E>(
    mut parser: P,
) -> impl FnMut(&'r [u8]) -> IResult<&'r [u8], CRCTreeNode<D>, E>
where
    P: Parser<&'r [u8], D, E>,
    E: ParseError<&'r [u8]>,
{
    move |input: &'r [u8]| -> IResult<&[u8], CRCTreeNode<D>, E> {
        let (input, crc) = map(le_u32, CRC::from_raw)(input)?;
        let (input, left) = le_i32(input)?;
        let (input, right) = le_i32(input)?;
        let (input, data) = parser.parse(input)?;
        Ok((
            input,
            CRCTreeNode {
                crc,
                left,
                right,
                data,
            },
        ))
    }
}

/// Parse a string after an u32 length specifier
pub fn parse_u32_string<'a, E>(input: &'a [u8]) -> IResult<&'a [u8], String, E>
where
    E: ParseError<&'a [u8]> + FromExternalError<&'a [u8], FromUtf8Error>,
{
    map_res(map(length_data(le_u32), Vec::from), String::from_utf8)(input)
}