From 056046f50c4c0c43eabf071d6915285bc1c8f472 Mon Sep 17 00:00:00 2001 From: rameel Date: Tue, 22 Sep 2026 22:19:42 +0500 Subject: [PATCH] parsers: report the name when a named Choice fails --- src/Ramstack.Parsing/Parser.Choice.cs | 1 + .../ParsersTests.Choice.cs | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/Ramstack.Parsing/Parser.Choice.cs b/src/Ramstack.Parsing/Parser.Choice.cs index e94b742..aaec335 100644 --- a/src/Ramstack.Parsing/Parser.Choice.cs +++ b/src/Ramstack.Parsing/Parser.Choice.cs @@ -110,6 +110,7 @@ public override bool TryParse(ref ParseContext context, [NotNullWhen(true)] out } context.RestoreDiagnosticState(state); + context.ReportExpected(Name); value = default; return false; } diff --git a/tests/Ramstack.Parsing.Tests/ParsersTests.Choice.cs b/tests/Ramstack.Parsing.Tests/ParsersTests.Choice.cs index 910328a..4cda6cf 100644 --- a/tests/Ramstack.Parsing.Tests/ParsersTests.Choice.cs +++ b/tests/Ramstack.Parsing.Tests/ParsersTests.Choice.cs @@ -47,4 +47,26 @@ public void ChoiceTest_2() parsers.Map(m => (m.Index, m.Length)).Parse("Sunset").Value, Is.EqualTo((0, 3))); } + + [Test] + public void Choice_NamedParser_ReportsName() + { + // The unnamed alternative makes this a ChoiceParser rather than + // DeferredDiagnosticChoiceParser. + var parser = Choice(L('a'), L('b').Between(L('('), L(')'))).As("value"); + + Assert.That( + parser.Parse("?").ErrorMessage, + Is.EqualTo("(1:1) Expected value")); + } + + [Test] + public void Choice_UnnamedParser_ReportsAlternatives() + { + var parser = Choice(L('a'), L('b').Between(L('('), L(')'))); + + Assert.That( + parser.Parse("?").ErrorMessage, + Is.EqualTo("(1:1) Expected 'a' or '('")); + } }