Skip to content
This repository was archived by the owner on Apr 2, 2026. It is now read-only.
This repository was archived by the owner on Apr 2, 2026. It is now read-only.

Map error with context? #948

Description

@tmke8

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())
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions