Skip to content

Commit b7dfcd5

Browse files
authored
Custom Parser can return null (#2140)
1 parent 6526806 commit b7dfcd5

File tree

3 files changed

+27
-3
lines changed

3 files changed

+27
-3
lines changed

src/System.CommandLine.Tests/ArgumentTests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Linq;
1010
using System.Threading.Tasks;
1111
using Xunit;
12+
using System.Net;
1213

1314
namespace System.CommandLine.Tests
1415
{
@@ -620,6 +621,29 @@ public void Custom_parser_can_pass_on_remaining_tokens(string commandLine)
620621
options => options.WithStrictOrdering());
621622
}
622623

624+
[Fact]
625+
public void Custom_parser_can_return_null()
626+
{
627+
CliOption<IPAddress> option = new("-ip")
628+
{
629+
CustomParser = (argumentResult) =>
630+
{
631+
string value = argumentResult.Tokens.Last().Value;
632+
if (IPAddress.TryParse(value, out var address))
633+
{
634+
return address;
635+
}
636+
637+
argumentResult.AddError($"'{value}' is not a valid value");
638+
return null;
639+
}
640+
};
641+
642+
ParseResult parseResult = new CliRootCommand() { option }.Parse("-ip a.b.c.d");
643+
644+
parseResult.Errors.Should().Contain(error => error.Message == "'a.b.c.d' is not a valid value");
645+
}
646+
623647
[Fact]
624648
public void When_tokens_are_passed_on_by_custom_parser_on_last_argument_then_they_become_unmatched_tokens()
625649
{

src/System.CommandLine/Argument{T}.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace System.CommandLine
1111
/// <inheritdoc cref="CliArgument" />
1212
public class CliArgument<T> : CliArgument
1313
{
14-
private Func<ArgumentResult, T>? _customParser;
14+
private Func<ArgumentResult, T?>? _customParser;
1515

1616
/// <summary>
1717
/// Initializes a new instance of the Argument class.
@@ -39,7 +39,7 @@ public CliArgument(string name) : base(name)
3939
/// The same instance can be set as <see cref="DefaultValueFactory"/>, in such case
4040
/// the delegate is also invoked when no input was provided.
4141
/// </remarks>
42-
public Func<ArgumentResult, T>? CustomParser
42+
public Func<ArgumentResult, T?>? CustomParser
4343
{
4444
get => _customParser;
4545
set

src/System.CommandLine/Option{T}.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public Func<ArgumentResult, T>? DefaultValueFactory
4242
}
4343

4444
/// <inheritdoc cref="CliArgument{T}.CustomParser" />
45-
public Func<ArgumentResult, T>? CustomParser
45+
public Func<ArgumentResult, T?>? CustomParser
4646
{
4747
get => _argument.CustomParser;
4848
set => _argument.CustomParser = value;

0 commit comments

Comments
 (0)