refactored LaunchArgumentParser
This commit is contained in:
parent
29cde170c6
commit
c461418185
@ -1,64 +1,96 @@
|
|||||||
namespace DTLib.Console;
|
namespace DTLib.Console;
|
||||||
|
|
||||||
#nullable enable
|
public record LaunchArgument
|
||||||
public class LaunchArgument
|
|
||||||
{
|
{
|
||||||
public string[] Aliases;
|
public struct Param
|
||||||
public string Description;
|
{
|
||||||
protected string? ParamName1;
|
public readonly string Name;
|
||||||
protected string? ParamName2;
|
public string? Value { get; internal set; } = null;
|
||||||
public Action? Handler;
|
|
||||||
public Action<string>? HandlerWithArg1;
|
|
||||||
public Action<string, string>? HandlerWithArg2;
|
|
||||||
public int RequiredArgsCount;
|
|
||||||
public int Priority;
|
|
||||||
|
|
||||||
private LaunchArgument(string[] aliases, string description, int priority)
|
public Param(string name)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly string[] Aliases;
|
||||||
|
public readonly string Description;
|
||||||
|
public readonly int Priority;
|
||||||
|
public readonly Param[] Params;
|
||||||
|
|
||||||
|
private readonly Action? Handler;
|
||||||
|
private readonly Action<string>? Handler1Param;
|
||||||
|
private readonly Action<string, string>? Handler2Params;
|
||||||
|
|
||||||
|
public LaunchArgument(string[] aliases, string description,
|
||||||
|
Action handler, int priority = 0)
|
||||||
{
|
{
|
||||||
Aliases = aliases;
|
Aliases = aliases;
|
||||||
Description = description;
|
Description = description;
|
||||||
Priority = priority;
|
Priority = priority;
|
||||||
}
|
|
||||||
|
|
||||||
public LaunchArgument(string[] aliases, string description,
|
|
||||||
Action handler, int priority = 0)
|
|
||||||
: this(aliases, description, priority)
|
|
||||||
{
|
|
||||||
Handler = handler;
|
Handler = handler;
|
||||||
RequiredArgsCount = 0;
|
Params = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public LaunchArgument(string[] aliases, string description,
|
public LaunchArgument(string[] aliases, string description,
|
||||||
Action<string> handler, string paramName1, int priority=0)
|
Action<string> handler, string paramName1, int priority=0)
|
||||||
: this(aliases, description, priority)
|
|
||||||
{
|
{
|
||||||
HandlerWithArg1 = handler;
|
Aliases = aliases;
|
||||||
ParamName1 = paramName1;
|
Description = description;
|
||||||
RequiredArgsCount = 1;
|
Priority = priority;
|
||||||
|
|
||||||
|
Handler1Param = handler;
|
||||||
|
Params = [
|
||||||
|
new Param(paramName1)
|
||||||
|
];
|
||||||
}
|
}
|
||||||
public LaunchArgument(string[] aliases, string description,
|
public LaunchArgument(string[] aliases, string description,
|
||||||
Action<string, string> handler, string paramName1, string paramName2, int priority=0)
|
Action<string, string> handler, string paramName1, string paramName2, int priority=0)
|
||||||
: this(aliases, description, priority)
|
|
||||||
{
|
{
|
||||||
HandlerWithArg2 = handler;
|
Aliases = aliases;
|
||||||
ParamName1 = paramName1;
|
Description = description;
|
||||||
ParamName2 = paramName2;
|
Priority = priority;
|
||||||
RequiredArgsCount = 2;
|
|
||||||
|
Handler2Params = handler;
|
||||||
|
Params = [
|
||||||
|
new Param(paramName1),
|
||||||
|
new Param(paramName2),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringBuilder AppendHelpInfo(StringBuilder b)
|
internal StringBuilder AppendHelpInfo(StringBuilder b)
|
||||||
{
|
{
|
||||||
b.Append(Aliases[0]);
|
b.Append(Aliases[0]);
|
||||||
for (int i = 1; i < Aliases.Length; i++)
|
for (int i = 1; i < Aliases.Length; i++)
|
||||||
b.Append(", ").Append(Aliases[i]);
|
b.Append(", ").Append(Aliases[i]);
|
||||||
if (!string.IsNullOrEmpty(ParamName1))
|
foreach (var param in Params)
|
||||||
b.Append(" [").Append(ParamName1).Append("] ");
|
b.Append(" [").Append(param.Name).Append("]");
|
||||||
if (!string.IsNullOrEmpty(ParamName2))
|
b.Append(" - ").Append(Description);
|
||||||
b.Append(" [").Append(ParamName2).Append("] ");
|
|
||||||
b.Append("- ").Append(Description);
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() =>
|
internal void Handle()
|
||||||
$"{{{{{Aliases.MergeToString(", ")}}}, Handler: {Handler is null}, HandlerWithArg: {HandlerWithArg1 is null}}}";
|
{
|
||||||
|
switch (Params.Length)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException(Params.Length.ToString());
|
||||||
|
case 0:
|
||||||
|
Handler!.Invoke();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (Params[0].Value is null)
|
||||||
|
throw new NullReferenceException($"Argument '{Aliases[0]}' hasnt got Param[0] value");
|
||||||
|
Handler1Param!.Invoke(Params[0].Value!);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (Params[0].Value is null)
|
||||||
|
throw new NullReferenceException($"Argument '{Aliases[0]}' hasnt got Param[0] value");
|
||||||
|
if (Params[1].Value is null)
|
||||||
|
throw new NullReferenceException($"Argument '{Aliases[0]}' hasnt got Param[1] value");
|
||||||
|
Handler2Params!.Invoke(Params[0].Value!, Params[1].Value!);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -2,9 +2,10 @@ namespace DTLib.Console;
|
|||||||
|
|
||||||
public class LaunchArgumentParser
|
public class LaunchArgumentParser
|
||||||
{
|
{
|
||||||
private Dictionary<string, LaunchArgument> argDict = new();
|
public bool IsAllowedNoArguments;
|
||||||
private List<LaunchArgument> argList = new();
|
|
||||||
public bool ExitIfNoArgs = true;
|
private readonly Dictionary<string, LaunchArgument> argDict = new();
|
||||||
|
private readonly List<LaunchArgument> argList = new();
|
||||||
|
|
||||||
public class ExitAfterHelpException : Exception
|
public class ExitAfterHelpException : Exception
|
||||||
{
|
{
|
||||||
@ -51,9 +52,9 @@ public class LaunchArgumentParser
|
|||||||
Add(helpArg);
|
Add(helpArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LaunchArgumentParser WithNoExit()
|
public LaunchArgumentParser AllowNoArguments()
|
||||||
{
|
{
|
||||||
ExitIfNoArgs = false;
|
IsAllowedNoArguments = true;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,15 +65,15 @@ public class LaunchArgumentParser
|
|||||||
}
|
}
|
||||||
public LaunchArgumentParser(params LaunchArgument[] arguments) : this()
|
public LaunchArgumentParser(params LaunchArgument[] arguments) : this()
|
||||||
{
|
{
|
||||||
for (var i = 0; i < arguments.Length; i++)
|
foreach (var arg in arguments)
|
||||||
Add(arguments[i]);
|
Add(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(LaunchArgument arg)
|
public void Add(LaunchArgument arg)
|
||||||
{
|
{
|
||||||
argList.Add(arg);
|
argList.Add(arg);
|
||||||
for(int a=0; a<arg.Aliases.Length; a++)
|
foreach (string alias in arg.Aliases)
|
||||||
argDict.Add(arg.Aliases[a], arg);
|
argDict.Add(alias, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LaunchArgument Parse(string argAlias)
|
public LaunchArgument Parse(string argAlias)
|
||||||
@ -93,8 +94,8 @@ public class LaunchArgumentParser
|
|||||||
/// <exception cref="ExitAfterHelpException">happens after help message is displayed</exception>
|
/// <exception cref="ExitAfterHelpException">happens after help message is displayed</exception>
|
||||||
public void ParseAndHandle(string[] args)
|
public void ParseAndHandle(string[] args)
|
||||||
{
|
{
|
||||||
// show help and throw
|
// show help message and throw ExitAfterHelpException
|
||||||
if (args.Length == 0 && ExitIfNoArgs)
|
if (args.Length == 0 && !IsAllowedNoArguments)
|
||||||
HelpHandler();
|
HelpHandler();
|
||||||
|
|
||||||
List<LaunchArgument> execQueue = new();
|
List<LaunchArgument> execQueue = new();
|
||||||
@ -102,34 +103,13 @@ public class LaunchArgumentParser
|
|||||||
for (int i = 0; i < args.Length; i++)
|
for (int i = 0; i < args.Length; i++)
|
||||||
{
|
{
|
||||||
LaunchArgument arg = Parse(args[i]);
|
LaunchArgument arg = Parse(args[i]);
|
||||||
|
for (int j = 0; j < arg.Params.Length; j++)
|
||||||
switch (arg.RequiredArgsCount)
|
|
||||||
{
|
{
|
||||||
case 0:
|
if (++i >= args.Length)
|
||||||
if (arg.Handler is null)
|
throw new Exception($"argument '{arg.Aliases[0]}' should have parameter '{arg.Params[j]}' after it");
|
||||||
throw new NullReferenceException($"argument <{args[i]}> hasn't got any handlers");
|
arg.Params[j].Value = args[i];
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
if (arg.HandlerWithArg1 is null)
|
|
||||||
throw new NullReferenceException($"argument <{args[i]}> hasn't got any handlers");
|
|
||||||
if (i + 1 >= args.Length)
|
|
||||||
throw new Exception($"argument <{args[i]}> should have a parameter after it");
|
|
||||||
string arg1 = args[++i];
|
|
||||||
arg.Handler = () => arg.HandlerWithArg1(arg1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
if (arg.HandlerWithArg2 is null)
|
|
||||||
throw new NullReferenceException($"argument <{args[i]}> hasn't got any handlers");
|
|
||||||
if (i + 2 >= args.Length)
|
|
||||||
throw new Exception($"argument <{args[i]}> should have two params after it");
|
|
||||||
string arg1 = args[++i], arg2 = args[++i];
|
|
||||||
arg.Handler = () => arg.HandlerWithArg2(arg1, arg2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
execQueue.Add(arg);
|
execQueue.Add(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,6 +117,6 @@ public class LaunchArgumentParser
|
|||||||
execQueue.Sort((a0, a1) => a0.Priority-a1.Priority);
|
execQueue.Sort((a0, a1) => a0.Priority-a1.Priority);
|
||||||
// finally executing handlers
|
// finally executing handlers
|
||||||
foreach (var a in execQueue)
|
foreach (var a in execQueue)
|
||||||
a.Handler!();
|
a.Handle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user