Skip to content
This repository was archived by the owner on Apr 2, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/combinator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ where
{
#[inline(always)]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
let found = inp.peek_maybe();
let before = inp.cursor();
// Remove the pre-inner alt, to be reinserted later so we always preserve it
let old_alt = inp.errors.alt.take();
Expand All @@ -260,30 +261,29 @@ where
let span = inp.span_since(&before);
let new_alt = inp.errors.alt.take();

inp.errors.alt = old_alt;
match res {
Ok(out) => {
if (self.filter)(&out) {
// If successful, reinsert the original alt and then apply the new alt on top of it, since both are valid
inp.errors.alt = old_alt;
if let Some(new_alt) = new_alt {
inp.add_alt_err(&new_alt.pos, new_alt.err);
}
Ok(M::bind(|| out))
} else {
// If unsuccessful, reinsert the original alt but replace the new alt with the "something else" error (since it overrides it)
let expected = [DefaultExpected::SomethingElse];
let err = E::Error::expected_found(expected, None, span);
inp.errors.alt = old_alt;
// TODO: Use something more detailed than the next token as the found
let err = E::Error::expected_found(expected, found, span);
Comment thread
Hedgehogo marked this conversation as resolved.
inp.add_alt_err(&before.inner, err);
Err(())
}
}

Err(_) => {
inp.errors.alt = old_alt;
if let Some(new_alt) = new_alt {
inp.add_alt_err(&new_alt.pos, new_alt.err);
}
// Can't fail!
let new_alt = new_alt.unwrap();
inp.add_alt_err(&new_alt.pos, new_alt.err);
Err(())
}
}
Expand Down
11 changes: 11 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3840,6 +3840,17 @@ mod tests {
fn filter() {
use crate::{DefaultExpected, LabelError};

let parser = just::<_, _, extra::Err<Rich<_>>>("a").filter(|_| false);

assert_eq!(
parser.parse("a").into_result(),
Err(vec![LabelError::<&str, _>::expected_found(
[DefaultExpected::SomethingElse],
Some('a'.into()),
SimpleSpan::new((), 0..1)
),])
);

let parser = group((
just("a").or_not(),
just("b").filter(|_| false).or_not(),
Expand Down