Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prefer parse implementation from Parse trait #69

Open
mauricelam opened this issue Oct 11, 2023 · 0 comments
Open

Prefer parse implementation from Parse trait #69

mauricelam opened this issue Oct 11, 2023 · 0 comments

Comments

@mauricelam
Copy link

If a type both implements the Parse trait, and has another parse function implemented directly, the generated code in nom-derive seems to prefer the direct parse function, even if the signature of it doesn't match.

Context

I was trying to parse a value-only enum, but with a twist that the remaining values should all go into an Unassigned enum that stores the value. I am using the Selector derived parse, but also provide a nom_derive::Parse trait implementation. The code looks roughly like the following:

#[derive(Nom, Debug, PartialEq, Eq)]
#[nom(Selector = "u32")]
#[repr(u32)]
pub enum DatalinkType {
    #[nom(Selector = "1001")]
    UnencapsulatedHci = 1001,
    #[nom(Selector = "1002")]
    HciUart = 1002,
    #[nom(Selector = "1005..=u32::MAX")]
    Unassigned(u32),
}

impl<'a> Parse<&'a [u8]> for DatalinkType {
    fn parse(i: &'a [u8]) -> nom::IResult<&'a [u8], Self, nom::error::Error<&'a [u8]>> {
        u32::parse_be(i)
            .and_then(|(rem, value)| DatalinkType::parse(i, value).map(|(_, dlt)| (rem, dlt)))
    }
}

However, when nesting this inside another struct, the generated code fails, because the parse function it found expects two arguments, instead of one, even though I implemented the Parse trait that has the correct signature.

#[derive(Nom, Debug)]
pub struct FileHeader<'a> {
    #[nom(Verify = "*version == 1")]
    pub version: u32,
    /// The datalink type for the packet records that follow.
    pub datalink_type: DatalinkType,
}

I had to add #[nom(Parse = "<DatalinkType as Parse<_>>::parse")] to get it to use the parse trait. Not sure if you would consider that a bug, but that behavior felt surprising to me, and I think it would be nice if it prefers the implementation from the Parse trait rather than trying to use an incompatible one.

My complete code is here: https://github.com/mauricelam/btsnoop-rs/pull/12/files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant