winnow-rs / winnow

Making parsing a breeze
https://docs.rs/winnow
Other
525 stars 40 forks source link

Regression: `dec_int` and `dec_uint` no longer parse "0" #475

Closed mernen closed 7 months ago

mernen commented 7 months ago

Please complete the following tasks

rust version

rustc 1.76.0 (07dca489a 2024-02-04)

winnow version

0.6.0

Minimal reproducible code

use winnow::ascii::{dec_int, dec_uint};
use winnow::Parser;

fn main() {
    let input = "0";

    let parsed_int = dec_int::<_, i32, ()>.parse(input);
    assert_eq!(parsed_int, Ok(0));

    let parsed_uint = dec_uint::<_, u32, ()>.parse(input);
    assert_eq!(parsed_uint, Ok(0));
}

Steps to reproduce the bug with the above code

Just cargo run. The input is already built-in.

Actual Behaviour

The single digit 0 is rejected by both dec_int and dec_uint.

Expected Behaviour

It should parse to the value 0.

Additional Context

This is caused by the refactoring in c8830bc34702f7a7d127bf2b9fccc4d894ccdd20, specifically:

https://github.com/winnow-rs/winnow/blob/c8830bc34702f7a7d127bf2b9fccc4d894ccdd20/src/ascii/mod.rs#L918

I assume the parser was written like this to reject an arbitrary number of leading zeros, but I'm not sure I see why. I can understand rejecting leading zeros when multiple bases are accepted, to avoid decimal/octal confusion. But in any context where the base is explicit (like the dec in the names here), it seems fine to me to accept zeros.

epage commented 7 months ago

I assume the parser was written like this to reject an arbitrary number of leading zeros, but I'm not sure I see why. I can understand rejecting leading zeros when multiple bases are accepted, to avoid decimal/octal confusion. But in any context where the base is explicit (like the dec in the names here), it seems fine to me to accept zeros.

People might be putting this in an alt with other bases.