-
I have a parser which parses keys and values in a map. After the key and value are parsed, I have a The problem I have is that when an error is printed, it shows an error location at the start of the file. In other words, when What I want, instead, is to have the error shown at the location of the key / value. Here's an example: fn style_prop(input: &mut &str) -> PResult<StyleProp> {
(
prop_name,
multispace0,
':',
multispace0,
alt((color, ident, length_list, length)).context(StrContext::Label("property value")),
)
.try_map(|(name, _, _, _, value)| match name {
"background_color" => Ok(StyleProp::BackgroundColor(value.coerce()?)),
"border_color" => Ok(StyleProp::BackgroundColor(value.coerce()?)),
"color" => Ok(StyleProp::Color(value.coerce()?)),
_ => Err(StyleParsingError::InvalidProperty),
})
.parse_next(input)
} Wrapping this rule in cut_err doesn't work, since that prevents the parser from detecting the end of the property list ('}'). |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 13 replies
-
This is not directly supported at this time. Composability is a known issue and is being tracked in #180. Some parsers solve this by creating a lot of combinations of these functions and I'd like to avoid that. This is easier to workaround when you are only applying it to one parser, like You could solve this by being less declarative. fn style_prop(input: &mut &str) -> PResult<StyleProp> {
let (name, _, _, _, value) = (
prop_name,
multispace0,
':',
multispace0,
alt((color, ident, length_list, length)).context(StrContext::Label("property value")),
).parse_next(input)?;
match name {
"background_color" => Ok(StyleProp::BackgroundColor(value.coerce()?)),
"border_color" => Ok(StyleProp::BackgroundColor(value.coerce()?)),
"color" => Ok(StyleProp::Color(value.coerce()?)),
_ => ErrMode::Cut(StyleParsingError::InvalidProperty),
}
} (error construction details left as an exercise for the reader ;) ) |
Beta Was this translation helpful? Give feedback.
What I overlooked in my message and yours is that
ErrMode::from_external_error
creates a backtracking error by default. You need to append.cut()
to it to make it work.Couple of tips
#[track_caller]
onrun_parser_err
andrun_parser
so you can more easily tell what failedassert!(err.contains("invalid property name:"));
toassert!(err.contains("invalid property name:"), "{err}");
so you have context on the failures.trace
parsers, like: