Skip to content

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

Open
@Railroad6230

Description

@Railroad6230

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions