diff --git a/DTLib/Console/LaunchArgument.cs b/DTLib/Console/LaunchArgument.cs index 57a5a65..eb560b3 100644 --- a/DTLib/Console/LaunchArgument.cs +++ b/DTLib/Console/LaunchArgument.cs @@ -1,64 +1,96 @@ namespace DTLib.Console; -#nullable enable -public class LaunchArgument +public record LaunchArgument { - public string[] Aliases; - public string Description; - protected string? ParamName1; - protected string? ParamName2; - public Action? Handler; - public Action? HandlerWithArg1; - public Action? HandlerWithArg2; - public int RequiredArgsCount; - public int Priority; + public struct Param + { + public readonly string Name; + public string? Value { get; internal set; } = null; + + public Param(string name) + { + Name = name; + } + } - private LaunchArgument(string[] aliases, string description, int priority) + public readonly string[] Aliases; + public readonly string Description; + public readonly int Priority; + public readonly Param[] Params; + + private readonly Action? Handler; + private readonly Action? Handler1Param; + private readonly Action? Handler2Params; + + public LaunchArgument(string[] aliases, string description, + Action handler, int priority = 0) { Aliases = aliases; Description = description; Priority = priority; - } - - public LaunchArgument(string[] aliases, string description, - Action handler, int priority = 0) - : this(aliases, description, priority) - { + Handler = handler; - RequiredArgsCount = 0; + Params = []; } public LaunchArgument(string[] aliases, string description, Action handler, string paramName1, int priority=0) - : this(aliases, description, priority) { - HandlerWithArg1 = handler; - ParamName1 = paramName1; - RequiredArgsCount = 1; + Aliases = aliases; + Description = description; + Priority = priority; + + Handler1Param = handler; + Params = [ + new Param(paramName1) + ]; } public LaunchArgument(string[] aliases, string description, Action handler, string paramName1, string paramName2, int priority=0) - : this(aliases, description, priority) { - HandlerWithArg2 = handler; - ParamName1 = paramName1; - ParamName2 = paramName2; - RequiredArgsCount = 2; + Aliases = aliases; + Description = description; + Priority = priority; + + Handler2Params = handler; + Params = [ + new Param(paramName1), + new Param(paramName2), + ]; } - public StringBuilder AppendHelpInfo(StringBuilder b) + internal StringBuilder AppendHelpInfo(StringBuilder b) { b.Append(Aliases[0]); for (int i = 1; i < Aliases.Length; i++) b.Append(", ").Append(Aliases[i]); - if (!string.IsNullOrEmpty(ParamName1)) - b.Append(" [").Append(ParamName1).Append("] "); - if (!string.IsNullOrEmpty(ParamName2)) - b.Append(" [").Append(ParamName2).Append("] "); - b.Append("- ").Append(Description); + foreach (var param in Params) + b.Append(" [").Append(param.Name).Append("]"); + b.Append(" - ").Append(Description); return b; } - public override string ToString() => - $"{{{{{Aliases.MergeToString(", ")}}}, Handler: {Handler is null}, HandlerWithArg: {HandlerWithArg1 is null}}}"; + internal void Handle() + { + 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; + } + } } \ No newline at end of file diff --git a/DTLib/Console/LaunchArgumentParser.cs b/DTLib/Console/LaunchArgumentParser.cs index cd779b0..2333b4a 100644 --- a/DTLib/Console/LaunchArgumentParser.cs +++ b/DTLib/Console/LaunchArgumentParser.cs @@ -2,9 +2,10 @@ namespace DTLib.Console; public class LaunchArgumentParser { - private Dictionary argDict = new(); - private List argList = new(); - public bool ExitIfNoArgs = true; + public bool IsAllowedNoArguments; + + private readonly Dictionary argDict = new(); + private readonly List argList = new(); public class ExitAfterHelpException : Exception { @@ -51,9 +52,9 @@ public class LaunchArgumentParser Add(helpArg); } - public LaunchArgumentParser WithNoExit() + public LaunchArgumentParser AllowNoArguments() { - ExitIfNoArgs = false; + IsAllowedNoArguments = true; return this; } @@ -64,15 +65,15 @@ public class LaunchArgumentParser } public LaunchArgumentParser(params LaunchArgument[] arguments) : this() { - for (var i = 0; i < arguments.Length; i++) - Add(arguments[i]); + foreach (var arg in arguments) + Add(arg); } public void Add(LaunchArgument arg) { argList.Add(arg); - for(int a=0; ahappens after help message is displayed public void ParseAndHandle(string[] args) { - // show help and throw - if (args.Length == 0 && ExitIfNoArgs) + // show help message and throw ExitAfterHelpException + if (args.Length == 0 && !IsAllowedNoArguments) HelpHandler(); List execQueue = new(); @@ -102,34 +103,13 @@ public class LaunchArgumentParser for (int i = 0; i < args.Length; i++) { LaunchArgument arg = Parse(args[i]); - - switch (arg.RequiredArgsCount) + for (int j = 0; j < arg.Params.Length; j++) { - case 0: - if (arg.Handler is null) - throw new NullReferenceException($"argument <{args[i]}> hasn't got any handlers"); - 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; - } + if (++i >= args.Length) + throw new Exception($"argument '{arg.Aliases[0]}' should have parameter '{arg.Params[j]}' after it"); + arg.Params[j].Value = args[i]; } + execQueue.Add(arg); } @@ -137,6 +117,6 @@ public class LaunchArgumentParser execQueue.Sort((a0, a1) => a0.Priority-a1.Priority); // finally executing handlers foreach (var a in execQueue) - a.Handler!(); + a.Handle(); } } \ No newline at end of file