Created
September 27, 2017 14:12
-
-
Save DrizztDoUrden/6694356f2fd8a5eec64413fcbaf874c0 to your computer and use it in GitHub Desktop.
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 System; | |
using System.Collections.Generic; | |
using System.Text; | |
namespace Validator | |
{ | |
public class ArgsParser | |
{ | |
public event Action OnExecute; | |
public event Action<string> OnUnresolvedKey; | |
public event Action<string> OnDuplicateArgument; | |
public bool IsRunning { get; private set; } | |
public string Description { get; set; } | |
public void Stop() => IsRunning = false; | |
public void AddCommand(string id, Action<Command> def) | |
{ | |
var cmd = new Command(Command.Types.Command, id, this); | |
def(cmd); | |
cmd.Parser.OnUnresolvedKey += key => OnUnresolvedKey?.Invoke(key); | |
cmd.Parser.OnDuplicateArgument += aid => OnDuplicateArgument?.Invoke(aid); | |
_commands.Add(cmd); | |
} | |
public void AddFlag(string id, Action<Command> def) | |
{ | |
var cmd = new Command(Command.Types.Flag, id, this); | |
def(cmd); | |
_commands.Add(cmd); | |
} | |
public void AddArgument(string id, Action<Command> def) | |
{ | |
var cmd = new Command(Command.Types.SingleValue, id, this); | |
def(cmd); | |
_commands.Add(cmd); | |
} | |
public void AddMultiArgument(string id, Action<Command> def) | |
{ | |
var cmd = new Command(Command.Types.MultiValue, id, this); | |
def(cmd); | |
_commands.Add(cmd); | |
} | |
public void AddHelpCommand(params string[] aliases) | |
{ | |
AddCommand("help", def => | |
{ | |
def.Desc = "Show help."; | |
def.Parser.OnExecute += () => ShowHelp(); | |
foreach (var alias in aliases) | |
def.Alias(alias); | |
}); | |
} | |
public int Execute(ArraySegment<string> args) | |
{ | |
IsRunning = true; | |
OnExecute?.Invoke(); | |
foreach (var cmd in _commands) | |
cmd.Found = false; | |
var i = 0; | |
for (; i < args.Count && IsRunning; i++) | |
{ | |
if (!_aliases.TryGetValue(args[i], out var cmd)) | |
{ | |
OnUnresolvedKey?.Invoke(args[i]); | |
continue; | |
} | |
if (cmd.Found && cmd.Type != Command.Types.MultiValue) | |
{ | |
OnDuplicateArgument?.Invoke(cmd.Id); | |
continue; | |
} | |
switch (cmd.Type) | |
{ | |
case Command.Types.Command: | |
i += cmd.Parser.Execute(new ArraySegment<string>(args.ToArray(), i, args.Count - i)); | |
break; | |
case Command.Types.MultiValue: | |
case Command.Types.SingleValue: | |
cmd.OnValue(args[++i]); | |
break; | |
case Command.Types.Flag: | |
cmd.OnValue("true"); | |
break; | |
} | |
cmd.Found = true; | |
} | |
return i; | |
} | |
public void ShowHelp(string intend = "") | |
{ | |
Console.WriteLine($"{intend}{Description}"); | |
foreach (var cmd in _commands) | |
{ | |
Console.WriteLine(); | |
cmd.PrintHelp(intend); | |
} | |
} | |
internal void RegisterAlias(string alias, Command command) | |
{ | |
_aliases.Add(alias, command); | |
} | |
private readonly List<Command> _commands = new List<Command>(); | |
private readonly Dictionary<string, Command> _aliases = new Dictionary<string, Command>(); | |
} | |
} |
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 System; | |
using System.Collections.Generic; | |
using System.Text; | |
namespace Validator | |
{ | |
public class Command | |
{ | |
public enum Types | |
{ | |
Command, | |
Flag, | |
SingleValue, | |
MultiValue, | |
} | |
public Action<string> OnValue; | |
public ArgsParser Parser = new ArgsParser(); | |
public string Id { get; } | |
public string Desc { get => Parser.Description; set => Parser.Description = value; } | |
public Types Type { get; } | |
public bool Found { get; set; } | |
public Command(Types type, string id, ArgsParser parser) | |
{ | |
Type = type; | |
Id = id; | |
_parser = parser; | |
} | |
public void Alias(string alias) | |
{ | |
_parser.RegisterAlias(alias, this); | |
_aliases.Add(alias); | |
} | |
public void PrintHelp(string intend = "") | |
{ | |
var aliases = string.Join(", ", _aliases); | |
var tags = $"[{TypeStr()}]"; | |
Intend(aliases, $"{intend} "); | |
Intend(tags, $"{intend} "); | |
Parser.ShowHelp($"{intend} "); | |
} | |
private readonly ArgsParser _parser; | |
private readonly List<string> _aliases = new List<string>(); | |
private void Intend(string line, string intend) | |
{ | |
var cw = Console.BufferWidth - intend.Length; | |
while (line.Length > 0) | |
{ | |
if (line.Length <= cw) | |
{ | |
Console.WriteLine($"{intend}{line}"); | |
line = ""; | |
break; | |
} | |
Console.WriteLine($"{intend}{line.Substring(0, cw)}"); | |
line = line.Substring(cw); | |
} | |
} | |
private string TypeStr() | |
{ | |
switch (Type) | |
{ | |
case Types.Command: | |
return "Command"; | |
case Types.Flag: | |
return "Flag"; | |
case Types.MultiValue: | |
return "Argument with multiple values"; | |
case Types.SingleValue: | |
return "Argument"; | |
default: | |
throw new ArgumentOutOfRangeException(nameof(Type)); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment