adrianaisemberg/CLAP

Handling of Nullables (int?)

joergbattermann opened this issue · 6 comments

Hello there,

I have a [Verb] with two int? / nullable parameters but CLAP throws an exception in case they are actually present:

CLAP.TypeConvertionException: '1' cannot be converted to System.Nullable1[System.Int32] ---> CLAP.TypeConvertionException: '1' cannot be converted to System.Nullable1[System.Int32]
at CLAP.ValuesFactory.ConvertParameterValue(String inputKey, String stringValue, Type parameterType, Exception deserializationException)
at CLAP.ValuesFactory.GetValueForParameter(Type parameterType, String inputKey, String stringValue)
--- End of inner exception stack trace ---
at CLAP.ValuesFactory.ConvertParameterValue(String inputKey, String stringValue, Type parameterType, Exception deserializationException)
at CLAP.ValuesFactory.GetValueForParameter(Type parameterType, String inputKey, String stringValue)
at CLAP.ValuesFactory.CreateParameterValues(String verb, Dictionary2 inputArgs, IEnumerable1 list)
at CLAP.ParserRunner.RunInternal(String[] args, Object obj)
at CLAP.ParserRunner.TryRunInternal(String[] args, Object obj)
at CLAP.MultiParser.RunTargets(String[] args, Object[] targets)
at CLAP.Parser.Run[T](String[] args)

.. the static method looks like this:

[Verb(IsDefault = true, Description = "Extracts the raw html stored in the CaliberRM database")]
public static void ExtractHtml(
[Parameter(Required = true)] string hostname,
[MoreThan(0)] [Parameter(Default = 20000, Required = false)]int port,
[Parameter(Required = true)] string username,
[Parameter(Required = true)] string password,
[Parameter(Required = true)] int requirementId,
[MoreThan(0)] [Parameter(Required = false)] int? majorVersion = null,
[MoreThan(0)] [Parameter(Required = false)] int? minorVersion = null)
{
// ...
}

Is there any way to use nullables or write my own type converter for CLAP?

Cheers and thanks for this awesome little library!
-J

Hi Jörg,

Congratulations! You have found a good bug!
I'll fix it ASAP and release a new version.
Unfortunately there isn't an option to write your own type converter.
Until this is resolved, you can define a const that will treated as a null value. This is a bad practice (and ugly as hell), but it will help you until I release the new version.
For example:

const int SomeConstAsNull = -999;
[Verb]
void Foo([Parameter(Default=SomeConstAsNull)] int x)
{
int? xx = x == SomeConstAsNull ? null : x;

// continue using xx instead of x ...
}

Thanks,
Adrian

OK. It's fixed now.
Please update your CLAP nuget (run "Update-Package clap" from your nuget console).

With this version, all the following are supported:

[Verb]
void Foo(
int? p1,
[Parameter(Default=5)] int? p2,
[Parameter(Default="5")] int? p3,
[Parameter(Default="")] int? p4,
[Parameter(Default=null)] int? p5)
{
}

Hope it solves your problem.

Thanks,
Adrian

And by-the-way, also custom types with nullable properties are supported:

class Data
{
public int? Number { get;set; }
}

class Program
{
[Verb]
void Foo(Data d)
{
}
}

and running as:

theexe foo id:{Number:5}

Adrian,

now how awesome is that.. fixed so quickly, great! I'll give it a try tomorrow morning but thanks :)

Have a nice evening and all the best,
-J

Cheers!

Confirmed, works!