-
Notifications
You must be signed in to change notification settings - Fork 483
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Usage of noun and verb with further parameters #932
Comments
hey @ImfeldC [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)]
public class NounAttribute : Attribute
{
public readonly string Name;
public NounAttribute(string nounName)
{
Name = nounName;
}
}
[Noun("tpm")]
[Verb("init")]
public class TpmInitArgs
{
// ...
}
[Noun("tpm")]
[Verb("show")]
public class TpmShowArgs
{
// ...
}
[Noun("dongle")]
[Verb("show")]
public class DongleShowArgs
{
// ...
} And add an extension method that handles the attribute: public static class ParserExtensions
{
public static ParserResult<object> ParseArgumentsWithNoun<T1, T2, T3>(this Parser parser, string[] args)
{
if (args.Length < 1)
{
// just return whatever as it will fail; there is no way to create NotParsed as it's sealed and ctor is internal
return parser.ParseArguments(args, []);
}
var types = new[] { typeof(T1), typeof(T2), typeof(T3) };
var nounTypesLookup = types
.SelectMany(t => t.GetTypeInfo().GetCustomAttributes<NounAttribute>().Select(attr => new {Type = t, Attribute = attr}))
.ToLookup(x => x.Attribute.Name, x => new {x.Type, x.Attribute});
if (!nounTypesLookup.Contains(args[0]))
{
// just return whatever as it will fail; there is no way to create NotParsed as it's sealed and ctor is internal
return parser.ParseArguments(args.Skip(1), types);
}
return parser.ParseArguments(args.Skip(1).ToArray(), nounTypesLookup[args[0]].Select(x => x.Type).ToArray());
}
}
public static class Program
{
public static void Main(string[] args)
{
Parser.Default.ParseArgumentsWithNoun<TpmInitArgs, TpmShowArgs, DongleShowArgs>(args)
.WithParsed<TpmInitArgs>(arg => { Console.WriteLine("TpmInitArgs"); })
.WithParsed<TpmShowArgs>(arg => { Console.WriteLine("TpmShowArgs"); })
.WithParsed<DongleShowArgs>(arg => { Console.WriteLine("DongleShowArgs"); });
}
} Although this solution would be a bit problematic:
What would be really amazing is a way to declare a Noun attribute on a class, and have the Verb attribute declared per field/property of a class, like so: [Noun("tpm")]
public class TpmArgs
{
[Verb("init")]
public TpmInitArgs TpmInitArgs;
[Verb("show")
public TpmShowArgs TpmShowArgs;
} which can be declared as simply as Parser.Default.ParseArguments<TpmArgs>(...) and would eventually map to particular args type in WithParsed .WithParsed<TpmInitArgs>( ... )
.WithParsed<TpmShowArgs>(... ) (kinda resembling how routes are declared in controllers in ASP.NET WebApi) |
Hi,
Is it possible to use CommandLineParser with noun and verb syntax? I would like to setup a command line tool, which supports different nouns (in CommandLineParser terminology, this would be a verb)
As example:
In the example above I have two levels of verbs, in the first level the noun and in the second level the verb.
Is this possible out-of-the-box? If not, are there ways to implement this?
The text was updated successfully, but these errors were encountered: