Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use nom take_while and is_digit for a &str input

Tags:

rust

nom

I'm trying to learn nom and have a problem where take_while does not accept is_digit or any other is_xxxx.

I have rows that I want to parse that looks like this

#123 = ABCDEF (...);

where I want to get the '123' part (and eventually the ABCDEF and the (...) parts as well. But one thing at the time I guess).

My parser currently looks like this

use nom::{
  bytes::complete::take_while,
  character::is_digit,
  error::ParseError,
  IResult
};

// Get row id
fn id<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, &'a str, E> {
    take_while(is_digit)(i)
}

The is_digit definition looks like this

pub fn is_digit(chr: u8) -> bool

And since the id parser takes a &str it will complain about the mismatch in types. But is it possible somehow to use the is_digit anyway? Can I do a type conversion somewhere without having to allocate anything. I really want this to be as efficient as possible.

It feels like the provided is_xxxx functions should be used in these kinds of situations, but I might be wrong about it.

Thanks!

like image 406
mottosson Avatar asked Oct 19 '25 07:10

mottosson


2 Answers

I know it doesn't directly answer your question because it doesn't directly use take_while but you could use the digit1 parser in character::complete::digit1.

It takes an &str and consumes 1 or more digits in [0..9] and returns an &str

like image 63
Steve Avatar answered Oct 20 '25 21:10

Steve


You can easily adapt is_digit to a char. First, all digits are valid ASCII, so we should check first if the character is ASCII. If it's ASCII, we can safely convert to u8.

// pub fn is_digit(chr: u8) -> bool;

pub fn is_char_digit(chr: char) -> bool {
    return chr.is_ascii() && is_digit(chr as u8)
}

You could also use the trait method is_dec_digit, which is just a wrapper for char.is_digit.

like image 41
Alexander Huszagh Avatar answered Oct 20 '25 21:10

Alexander Huszagh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!