Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch string between tags with nom delimited

Tags:

rust

nom

I'm trying to learn to use nom (5.0.1) and want to get the string between two tags:

use nom::{
    bytes::complete::{tag_no_case, take_while},
    character::{is_alphanumeric},
    error::{ParseError},
    sequence::{delimited},
    IResult,
};

fn root<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, &str, E> {
    delimited(
        tag_no_case("START;"),
        take_while(is_alphanumeric),
        tag_no_case("END;"),
    )(i)
}

But this gives me the error

error[E0271]: type mismatch resolving `<&str as nom::InputTakeAtPosition>::Item == u8`
   --> src/main.rs:128:9
    |
128 |         take_while(is_alphanumeric),
    |         ^^^^^^^^^^^ expected char, found u8

What have I done wrong here? I'm fairly new to Rust and a total beginner with nom so I'm expecting it to be something really obvious in the end :)

like image 777
mottosson Avatar asked Sep 19 '25 20:09

mottosson


2 Answers

The is_alphanumeric from nom expects a parameter of type u8, but you give it a char. Use is_alphanumeric from std instead:

fn root<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, &str, E> {
    delimited(
        tag_no_case("START;"),
        take_while(char::is_alphanumeric),
        tag_no_case("END;"),
    )(i)
}
like image 65
edwardw Avatar answered Sep 23 '25 10:09

edwardw


I don't have all the info needed (exact type of take_while and is_alphanumeric), so I'll try to approximate one.


As you want take_while(F)(i) to returns &str (ie. almost &[char]), then take_while(F) must have type impl Fn(&[char]) -> IResult<&[char], &[char], Error>.

However, take_while takes an argument of type Fn(<Input as InputTakeAtPosition>::Item) -> bool, and returns impl Fn(Input) -> IResult<Input, Input, Error>.

So, this means F the argument to take_while must have type Fn(&[char]) -> IResult<&[char], &[char], Error>

Does your is_alphanumeric have this type, or is it Fn(&[u8]) -> IResult<&[u8], &[u8], Error>?


Or it could be the opposite, you may have a take_while that works on &[u8], which doesn't work with your function that takes and returns &str (which, again, is mostly a &[char], and absolutely not a &[u8])

like image 40
Valentin Lorentz Avatar answered Sep 23 '25 11:09

Valentin Lorentz