I'm parsing Rust-style raw strings which can look like: ###"hi"##string continues"### where I need to use context to count the number of hashes. This works with count(), ignore_with_ctx, configure and exactly.
However, in cases where this fails, I want to report a nice error, and for this error I need to know the number of hashes. There is map_err_with_state, which can access the state, but there is no map_err_with that can access the parser context.
Am I missing something and this is somehow possible or is this functionality missing?
EDIT: my current code, in case it helps:
fn raw_string<'src>() -> impl Parser<'src, &'src str, Box<str>, extra::Err<ParseError>> + Clone {
let matching_hashes = just('#')
.repeated()
.configure(|cfg, hash_num| cfg.exactly(*hash_num));
just('#')
.repeated()
.at_least(1)
.count()
.then_ignore(just('"'))
.ignore_with_ctx(
any()
.and_is(just('"').then(matching_hashes).not())
.repeated()
.to_slice()
.then(just('"').ignore_then(matching_hashes.ignored()))
.map_err_with_state(move |e: ParseError, span: SimpleSpan, _state| {
let hash_num = ???; // how to get the value in here?
if matches!(
&e,
ParseError::Unexpected {
found: TokenFormat::Eoi,
..
}
) {
e.merge(ParseError::Unclosed {
label: "raw string",
opened_at: Span::from(span).before_start(hash_num + 2),
opened: TokenFormat::OpenRaw(hash_num),
expected_at: Span::from(span).at_end(),
expected: TokenFormat::CloseRaw(hash_num),
found: None.into(),
})
} else {
e
}
}),
)
.map(|text| text.0.into())
}
I'm parsing Rust-style raw strings which can look like:
###"hi"##string continues"###where I need to use context to count the number of hashes. This works withcount(),ignore_with_ctx,configureandexactly.However, in cases where this fails, I want to report a nice error, and for this error I need to know the number of hashes. There is
map_err_with_state, which can access the state, but there is nomap_err_withthat can access the parser context.Am I missing something and this is somehow possible or is this functionality missing?
EDIT: my current code, in case it helps: