Last active
April 17, 2019 13:24
-
-
Save tintoy/8e22ac81d6b206fd6489f5d07428a7c5 to your computer and use it in GitHub Desktop.
Sub-verbs command line parser
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using CommandLine; | |
using CommandLine.Text; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
namespace SubVerbs | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
Command currentCommand = null; | |
ParserResult<object> result = Parser.Default | |
.ParseArguments(args, | |
typeof(Verb1Command), | |
typeof(Verb2Command) | |
) | |
.WithParsed( | |
command => currentCommand = (Command)command | |
); | |
while (currentCommand != null) | |
{ | |
switch (currentCommand) | |
{ | |
case CompoundVerbCommand compoundVerb: | |
{ | |
if (currentCommand != null) | |
Console.WriteLine($"CompoundVerbCommand: {currentCommand}"); | |
IEnumerable<string> remainingArgs = compoundVerb.RemainingArgs ?? Enumerable.Empty<string>(); | |
Parser.Default | |
.ParseArguments(remainingArgs.DefaultIfEmpty("help"), | |
compoundVerb.SubVerbTypes.ToArray() | |
) | |
.WithParsed( | |
command => currentCommand = (Command)command | |
) | |
.WithNotParsed( _ => currentCommand = null ); | |
break; | |
} | |
case Command command: | |
{ | |
Console.WriteLine( $"Command: {currentCommand}" ); | |
goto done; | |
} | |
} | |
} | |
done: | |
if (currentCommand != null) | |
Console.WriteLine( $"Final: {currentCommand}" ); | |
} | |
} | |
public abstract class Command | |
{ | |
} | |
public abstract class CompoundVerbCommand | |
: Command | |
{ | |
public abstract IEnumerable<Type> SubVerbTypes { get; } | |
[Value(0)] | |
public IEnumerable<string> RemainingArgs { get; set; } | |
} | |
[Verb("verb1", HelpText = "Verb 1")] | |
public sealed class Verb1Command | |
: CompoundVerbCommand | |
{ | |
[Option("ho")] | |
public bool Ho { get; set; } | |
[Option("pip")] | |
public int Pip { get; set; } | |
public override string ToString() => $"Verb1(Ho={Ho}, Pip={Pip})"; | |
public override IEnumerable<Type> SubVerbTypes | |
{ | |
get | |
{ | |
yield return typeof(Verb1FooCommand); | |
yield return typeof(Verb1BarCommand); | |
} | |
} | |
} | |
[Verb("foo", HelpText = "Verb 1 Foo")] | |
public sealed class Verb1FooCommand | |
: Command | |
{ | |
public override string ToString() => "Verb1Foo()"; | |
} | |
[Verb("bar", HelpText = "Verb 1 Bar")] | |
public sealed class Verb1BarCommand | |
: CompoundVerbCommand | |
{ | |
public override string ToString() => "Verb1Bar()"; | |
public override IEnumerable<Type> SubVerbTypes | |
{ | |
get | |
{ | |
yield return typeof(Verb1BarDiddlyCommand); | |
yield return typeof(Verb1BarBoCommand); | |
} | |
} | |
} | |
[Verb("diddly", HelpText = "Verb 1 Bar Diddly")] | |
public sealed class Verb1BarDiddlyCommand | |
: Command | |
{ | |
public override string ToString() => "Verb1BarDiddly()"; | |
} | |
[Verb("bo", HelpText = "Verb 1 Bar Bo")] | |
public sealed class Verb1BarBoCommand | |
: Command | |
{ | |
public override string ToString() => "Verb1BarBo()"; | |
} | |
[Verb("verb2", HelpText = "Verb 2")] | |
public sealed class Verb2Command | |
: CompoundVerbCommand | |
{ | |
public override string ToString() => "Verb2()"; | |
public override IEnumerable<Type> SubVerbTypes | |
{ | |
get | |
{ | |
yield return typeof(Verb2BazCommand); | |
yield return typeof(Verb2BonkCommand); | |
} | |
} | |
} | |
[Verb("baz", HelpText = "Verb 2 Baz")] | |
public sealed class Verb2BazCommand | |
: Command | |
{ | |
public override string ToString() => "Verb2Baz()"; | |
} | |
[Verb("bonk", HelpText = "Verb 2 Bonk")] | |
public sealed class Verb2BonkCommand | |
: Command | |
{ | |
public override string ToString() => "Verb2Bonk()"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment