I'm trying to parse indentation levels with the following function:
fn get_indent_level(input: &str) -> usize {
let (_, result) = many0_count(alt((tag("L_ "), tag("| "), tag(" "))))(input).unwrap_or_default();
result
}
I got this compiler error:
error[E0283]: type annotations needed
--> src\lib.rs:149:23
|
149 | let (_, result) = many0_count(alt((tag("L_ "), tag("| "), tag(" "))))(input).unwrap_or_default();
| ^^^^^^^^^^^ cannot infer type for type parameter `E` declared on the function `many0_count`
|
::: C:\Users\user1\.cargo\registry\src\github.com-xxxxxxxxxxxxxxx\nom-6.2.1\src\multi\mod.rs:486:6
|
486 | E: ParseError<I>,
| ------------- required by this bound in `many0_count`
|
= note: cannot satisfy `_: ParseError<&str>`
help: consider specifying the type arguments in the function call
|
149 | let (_, result) = many0_count::<I, O, E, F>(alt((tag("L_ "), tag("| "), tag(" "))))(input).unwrap_or_default();
| ^^^^^^^^^^^^^^
When I add the types like this:
fn get_indent_level(input: &str) -> usize {
let (_, result) = many0_count::<&str, usize, nom::error::ErrorKind, &str>(alt((tag("L_ "), tag("| "), tag(" "))))(input).unwrap_or_default();
result
}
I get this new error:
error[E0277]: the trait bound `nom::error::ErrorKind: ParseError<&str>` is not satisfied
--> src\lib.rs:149:23
|
149 | let (_, result) = many0_count::<&str, usize, nom::error::ErrorKind, &str>(alt((tag("L_ "), tag("| "), tag(" "))))(input).unwrap_or...
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `ParseError<&str>` is not implemented for `nom::error::ErrorKind`
|
::: C:\Users\user1\.cargo\registry\src\github.com-xxxxxxxxxx\nom-6.2.1\src\multi\mod.rs:486:6
|
486 | E: ParseError<I>,
| ------------- required by this bound in `many0_count`
What's the proper way to add types and fix the issue?
You only need to specify the error type, because nom can return different error types and the compiler cannot infer it, because the error is not used anywhere. You can use the _
syntax to let the compiler infer the rest of the known types.
The easiest way is to specify the types on the IResult
type, because it requires less types than many0_count()
:
fn get_indent_level(input: &str) -> usize {
let result: IResult<_, _, nom::error::Error<_>> =
many0_count(alt((
tag("L_ "),
tag("| "),
tag(" ")
)))(input);
result.map(|(_, x)| x).unwrap_or_default()
}
In that way you only need to provide 3 types, 2 of which are already known (the input - &str
; and the result - usize
) so you can let the compiler infer them using the _
syntax and manually write only the error type.