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

Parser::into, From trait and chained parsers. #1839

Open
Railroad6230 opened this issue Mar 18, 2025 · 0 comments
Open

Parser::into, From trait and chained parsers. #1839

Railroad6230 opened this issue Mar 18, 2025 · 0 comments

Comments

@Railroad6230
Copy link

Hi nom,

I'm writing a parser, and at some point I wanted to use the Parser::into method:

use nom::bytes::complete::take;
use nom::number::complete::{le_u64, le_u8};
use nom::{IResult, Parser};

pub struct MyType<'a> {
    pub content: &'a [u8],
    pub code: u8,
}

impl<'a> From<(u8, &'a [u8])> for MyType<'a> {
    fn from((code, content): (u8, &'a [u8])) -> Self {
        Self { content, code }
    }
}

fn base_parser(input: &[u8]) -> IResult<&[u8], (u8, &[u8])> {
    le_u8.and(le_u64.flat_map(take)).parse(input)
}

pub fn parse(input: &[u8]) -> IResult<&[u8], MyType> {
    base_parser.into().parse(input)
}

However, this leads to the following error:

error[E0034]: multiple applicable items in scope
  --> src/test.rs:29:17
   |
29 |     base_parser.into().parse(input)
   |                 ^^^^ multiple `into` found
   |
   = note: candidate #1 is defined in an impl of the trait `nom::Parser` for the type `F`
   = note: candidate #2 is defined in an impl of the trait `std::convert::Into` for the type `T`
help: disambiguate the method for candidate #1
   |
29 |     nom::Parser::into(base_parser).parse(input)
   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
help: disambiguate the method for candidate #2
   |
29 |     std::convert::Into::into(base_parser).parse(input)
   | 

This error sounds correct and legit to me, and I've found the following workarounds:

pub fn parse(input: &[u8]) -> IResult<&[u8], MyType> {
    Parser::into(base_parser).parse(input)
}

pub fn parse(input: &[u8]) -> IResult<&[u8], MyType> {
    base_parser.map(MyType::from).parse(input)
}

I was wondering if the Parser::into(sub_parser) is the preferred form here?

I wanted to write my parser using chained parsers (parser1.then(parser2).and_then(parser3).or(parser4)) instead
of wrapped parsers (tuple(map(opt(…)))), but because of this error it seems that I will not be able to.

I think that renaming Parser::into to something else would solve it, but this may not be what you want.

I'm using nom 8.0.0 with rust 1.85.0.

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