command-line-api icon indicating copy to clipboard operation
command-line-api copied to clipboard

add `Uri` to `ArgumentConverter.StringConverters`

Open andrewschmidgit opened this issue 6 months ago • 4 comments

Right now, if you have:

public class UrlOption : Option<Uri>
{
  public UrlOption() : base("--url")
  {
    Required = true;
  }
}

an InvalidOperationException is thrown, with the message:

Cannot parse argument 'http://example.com' for option '--url' as expected type 'System.Uri'.

andrewschmidgit avatar Jun 18 '25 19:06 andrewschmidgit

The workaround I'm using is

public class ExampleCommand : Command
{
    public ExampleCommand() : base("example")
    {
        Option<string> urlOption = new("--url")
        {
            Required = true,
        };

        urlOption.Validators.Add(result =>
        {
            var url = result.GetRequiredValue(urlOption);
            if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
                result.AddError($"'{url}' is not a well-formed uri");
        });

        Options.Add(urlOption);

        SetAction(async (result, cancellation) =>
        {
            Uri url = new(result.GetRequiredValue(urlOption));

            logger.LogInformation("handling url: {}", url);

            await Task.CompletedTask;
            logger.LogInformation("handled");
        });
    }
}

andrewschmidgit avatar Jun 18 '25 19:06 andrewschmidgit

Using Option.CustomParser combines validation and strong typing so that you can use Option<Uri>.

jonsequitur avatar Jun 18 '25 19:06 jonsequitur

wow thank you. should've looked a little harder, I see that example in TypeConversionTests.cs

andrewschmidgit avatar Jun 18 '25 19:06 andrewschmidgit

Reopening while we discuss whether to include Uri support by default. It's such a common type it's probably worthwhile.

jonsequitur avatar Jun 18 '25 21:06 jonsequitur