mirror of
https://github.com/Stone-Red-Code/Commander.NET.git
synced 2026-09-04 08:56:09 +02:00
- Add Result Code and Help function
This commit is contained in:
@@ -0,0 +1,126 @@
|
|||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Commander_Net;
|
||||||
|
|
||||||
|
public class Command
|
||||||
|
{
|
||||||
|
public string[] Identifiers { get; init; }
|
||||||
|
public Func<string, CommandResult> Method { get; init; }
|
||||||
|
public HelpText HelpText { get; init; }
|
||||||
|
|
||||||
|
internal readonly List<Command> subCommands = new();
|
||||||
|
|
||||||
|
internal Command(Func<string, CommandResult> method, HelpText description, string[] identifiers)
|
||||||
|
{
|
||||||
|
Method = method;
|
||||||
|
HelpText = description;
|
||||||
|
Identifiers = identifiers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command()
|
||||||
|
{
|
||||||
|
Identifiers = Array.Empty<string>();
|
||||||
|
HelpText = string.Empty;
|
||||||
|
Method = new Func<string, CommandResult>((_) => CommandResult.Success);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command Register(Action<string> method, params string[] identifiers)
|
||||||
|
{
|
||||||
|
return Register(method, new HelpText(), identifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command Register(Func<string, CommandResult> method, params string[] identifiers)
|
||||||
|
{
|
||||||
|
return Register(method, new HelpText(), identifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command Register(Action<string> method, HelpText description, params string[] identifiers)
|
||||||
|
{
|
||||||
|
Func<string, CommandResult> commandMethod = (input) =>
|
||||||
|
{
|
||||||
|
method(input);
|
||||||
|
return new CommandResult(ResultType.Success);
|
||||||
|
};
|
||||||
|
|
||||||
|
return Register(commandMethod, description, identifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command Register(Func<string, CommandResult> method, HelpText description, params string[] identifiers)
|
||||||
|
{
|
||||||
|
Command command = new Command(method, description, identifiers);
|
||||||
|
Register(command);
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command Register(Command command)
|
||||||
|
{
|
||||||
|
subCommands.Add(command);
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal List<CommandResult> ExecuteMultible(string input, List<CommandResult>? commandResults = null)
|
||||||
|
{
|
||||||
|
string[] inputParts = input.Split(' ');
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
commandResults ??= new List<CommandResult>();
|
||||||
|
|
||||||
|
foreach (Command? command in subCommands.Where(command => command.Identifiers.Contains(inputParts[0])))
|
||||||
|
{
|
||||||
|
command.ExecuteMultible(string.Join(' ', inputParts.Skip(1)), commandResults);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
CommandResult result;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = Method(input);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
result = new CommandResult(ResultType.UnexpectedError);
|
||||||
|
}
|
||||||
|
|
||||||
|
commandResults.Add(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return commandResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal CommandResult Execute(string input)
|
||||||
|
{
|
||||||
|
string[] inputParts = input.Split(' ');
|
||||||
|
|
||||||
|
Command? command = subCommands.FirstOrDefault(command => command.Identifiers.Contains(inputParts[0]));
|
||||||
|
|
||||||
|
if (command is not null)
|
||||||
|
{
|
||||||
|
return command.Execute(string.Join(' ', inputParts.Skip(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Method(input);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return new CommandResult(ResultType.UnexpectedError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal string GetHelp(string input)
|
||||||
|
{
|
||||||
|
string[] inputParts = input.Split(' ');
|
||||||
|
|
||||||
|
StringBuilder helpText = new StringBuilder($"{string.Join(" | ", Identifiers)} > {HelpText?.Description}");
|
||||||
|
|
||||||
|
foreach (Command command in subCommands.Where(command => command.Identifiers.Contains(inputParts[0]) || string.IsNullOrWhiteSpace(input)))
|
||||||
|
{
|
||||||
|
helpText.Append($"{Environment.NewLine} {command.GetHelp(string.Join(' ', inputParts.Skip(1)))}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return helpText.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
namespace Commander_Net;
|
||||||
|
|
||||||
|
public class CommandResult
|
||||||
|
{
|
||||||
|
public ResultType ResultType { get; }
|
||||||
|
public string Message { get; }
|
||||||
|
|
||||||
|
public static CommandResult Success => new CommandResult(ResultType.Success);
|
||||||
|
public static CommandResult InvalidInput => new CommandResult(ResultType.InvalidInput);
|
||||||
|
public static CommandResult InternalError => new CommandResult(ResultType.InternalError);
|
||||||
|
|
||||||
|
public CommandResult(ResultType type, string message = "")
|
||||||
|
{
|
||||||
|
ResultType = type;
|
||||||
|
Message = message;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Commander_Net;
|
||||||
|
|
||||||
|
public enum ResultType
|
||||||
|
{
|
||||||
|
Success,
|
||||||
|
InvalidInput,
|
||||||
|
InternalError,
|
||||||
|
UnexpectedError
|
||||||
|
}
|
||||||
@@ -4,6 +4,28 @@
|
|||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
|
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||||
|
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||||
|
<PackageId>Console.$(AssemblyName)</PackageId>
|
||||||
|
<RootNamespace>Commander_Net</RootNamespace>
|
||||||
|
<RepositoryUrl>https://github.com/Stone-Red-Code/Commander.NET</RepositoryUrl>
|
||||||
|
<PackageTags>CLI, Console, Commands</PackageTags>
|
||||||
|
<Product>$(AssemblyName)</Product>
|
||||||
|
<AssemblyVersion>1.0.1.0</AssemblyVersion>
|
||||||
|
<FileVersion>1.0.1.0</FileVersion>
|
||||||
|
<Version>1.0.1.0</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\README.md">
|
||||||
|
<Pack>True</Pack>
|
||||||
|
<PackagePath>\</PackagePath>
|
||||||
|
</None>
|
||||||
|
<None Include="..\LICENSE">
|
||||||
|
<Pack>True</Pack>
|
||||||
|
<PackagePath>\</PackagePath>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
+75
-50
@@ -1,45 +1,6 @@
|
|||||||
namespace Commander_Net;
|
using System.Text;
|
||||||
|
|
||||||
public class Command
|
namespace Commander_Net;
|
||||||
{
|
|
||||||
internal string[] Identifiers { get; }
|
|
||||||
|
|
||||||
internal readonly Action<string> method;
|
|
||||||
internal readonly List<Command> subCommands = new();
|
|
||||||
|
|
||||||
public Command(Action<string> method, string[] identifiers)
|
|
||||||
{
|
|
||||||
this.method = method;
|
|
||||||
Identifiers = identifiers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Command Register(Action<string> method, params string[] identifiers)
|
|
||||||
{
|
|
||||||
Command command = new Command(method, identifiers);
|
|
||||||
subCommands.Add(command);
|
|
||||||
return command;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void Execute(string input)
|
|
||||||
{
|
|
||||||
string[] inputParts = input.Split(' ');
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
foreach (Command? command in subCommands)
|
|
||||||
{
|
|
||||||
if (command.Identifiers.Contains(inputParts[0]))
|
|
||||||
{
|
|
||||||
command.Execute(string.Join(' ', inputParts.Skip(1)));
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
method.Invoke(input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Commander
|
public class Commander
|
||||||
{
|
{
|
||||||
@@ -47,25 +8,89 @@ public class Commander
|
|||||||
|
|
||||||
public Command Register(Action<string> method, params string[] identifiers)
|
public Command Register(Action<string> method, params string[] identifiers)
|
||||||
{
|
{
|
||||||
Command command = new Command(method, identifiers);
|
return Register(method, new HelpText(), identifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command Register(Func<string, CommandResult> method, params string[] identifiers)
|
||||||
|
{
|
||||||
|
return Register(method, new HelpText(), identifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command Register(Action<string> method, HelpText description, params string[] identifiers)
|
||||||
|
{
|
||||||
|
Func<string, CommandResult> commandMethod = (input) =>
|
||||||
|
{
|
||||||
|
method(input);
|
||||||
|
return new CommandResult(ResultType.Success);
|
||||||
|
};
|
||||||
|
|
||||||
|
return Register(commandMethod, description, identifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command Register(Func<string, CommandResult> method, HelpText description, params string[] identifiers)
|
||||||
|
{
|
||||||
|
Command command = new Command(method, description, identifiers);
|
||||||
|
Register(command);
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command Register(Command command)
|
||||||
|
{
|
||||||
commands.Add(command);
|
commands.Add(command);
|
||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Execute(string input)
|
public bool ExecuteMultible(string input, out List<CommandResult> commandResults)
|
||||||
{
|
{
|
||||||
|
List<CommandResult> internalCommandResults = new List<CommandResult>();
|
||||||
string[] inputParts = input.Split(' ');
|
string[] inputParts = input.Split(' ');
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
foreach (Command? command in commands.Where(command => command.Identifiers.Contains(inputParts[0])))
|
||||||
foreach (Command? command in commands)
|
|
||||||
{
|
{
|
||||||
if (command.Identifiers.Contains(inputParts[0]))
|
List<CommandResult> tempCommandResults = command.ExecuteMultible(string.Join(' ', inputParts.Skip(1)));
|
||||||
{
|
internalCommandResults.AddRange(tempCommandResults);
|
||||||
command.Execute(string.Join(' ', inputParts.Skip(1)));
|
found = true;
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commandResults = internalCommandResults;
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool Execute(string input, out CommandResult? commandResult)
|
||||||
|
{
|
||||||
|
string[] inputParts = input.Split(' ');
|
||||||
|
|
||||||
|
Command? command = commands.FirstOrDefault(command => command.Identifiers.Contains(inputParts[0]));
|
||||||
|
|
||||||
|
if (command is null)
|
||||||
|
{
|
||||||
|
commandResult = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
commandResult = command.Execute(string.Join(' ', inputParts.Skip(1)));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetHelp(string input, out string helpText)
|
||||||
|
{
|
||||||
|
string[] inputParts = input.Split(' ');
|
||||||
|
|
||||||
|
StringBuilder internalHelpText = new StringBuilder();
|
||||||
|
|
||||||
|
foreach (Command command in commands.Where(command => command.Identifiers.Contains(inputParts[0]) || string.IsNullOrWhiteSpace(input)))
|
||||||
|
{
|
||||||
|
internalHelpText.AppendLine(command.GetHelp(string.Join(' ', inputParts.Skip(1))));
|
||||||
|
}
|
||||||
|
|
||||||
|
helpText = internalHelpText.ToString();
|
||||||
|
return !string.IsNullOrWhiteSpace(helpText);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool PrintHelp(string input)
|
||||||
|
{
|
||||||
|
bool result = GetHelp(input, out string helpText);
|
||||||
|
Console.WriteLine(helpText.TrimEnd('\n', '\r'));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
namespace Commander_Net;
|
||||||
|
|
||||||
|
public class HelpText
|
||||||
|
{
|
||||||
|
public string? Description { get; init; }
|
||||||
|
|
||||||
|
public HelpText(string? description)
|
||||||
|
{
|
||||||
|
Description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal HelpText()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
public static implicit operator HelpText(string helpText)
|
||||||
|
{
|
||||||
|
return new HelpText(helpText);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -3,17 +3,38 @@
|
|||||||
Console.WriteLine("Hello, World!");
|
Console.WriteLine("Hello, World!");
|
||||||
|
|
||||||
Commander commander = new Commander();
|
Commander commander = new Commander();
|
||||||
Command sayCommand = commander.Register(HahaYes, "say", "tell");
|
Command sayCommand = commander.Register(HahaYes, "say", "yell");
|
||||||
sayCommand.Register(HahaYesSub, "kek");
|
sayCommand.Register(HahaYesSub, "kek");
|
||||||
|
|
||||||
commander.Register(HahaNo, "scream", "yell");
|
commander.Register(HahaNo, "scream", "yell");
|
||||||
commander.Register((args) => Console.Clear(), "clear");
|
commander.Register((args) => Console.Clear(), "clear");
|
||||||
|
commander.Register((input) => commander.PrintHelp(input) ? CommandResult.Success : CommandResult.InvalidInput, "help");
|
||||||
|
|
||||||
|
Command fancyCommand = commander.Register(_ => new CommandResult(ResultType.InvalidInput, "How about no?"), "fancy");
|
||||||
|
fancyCommand.Register(new Command()
|
||||||
|
{
|
||||||
|
Identifiers = new string[] { "yes", "YES" },
|
||||||
|
HelpText = "Says that the input is fancy",
|
||||||
|
|
||||||
|
Method = (i) => { Console.WriteLine($"Yes, {i} is very fancy!"); return new CommandResult(ResultType.Success); }
|
||||||
|
});
|
||||||
|
|
||||||
|
fancyCommand.Register(new Command()
|
||||||
|
{
|
||||||
|
Identifiers = new string[] { "no", "NO" },
|
||||||
|
HelpText = "Says that the input is not fancy",
|
||||||
|
Method = (i) => { Console.WriteLine($"Yes, {i} is not very fancy!"); return new CommandResult(ResultType.Success); }
|
||||||
|
});
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (!commander.Execute(Console.ReadLine()!))
|
if (commander.ExecuteMultible(Console.ReadLine()!, out List<CommandResult> commandResult))
|
||||||
{
|
{
|
||||||
Console.WriteLine("Command not found!");
|
commandResult.ForEach((e) => Console.WriteLine(e.ResultType + " " + e.Message));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("xxx Command not found!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,7 +48,14 @@ void HahaYesSub(string yes)
|
|||||||
Console.WriteLine($">>> {yes} xD");
|
Console.WriteLine($">>> {yes} xD");
|
||||||
}
|
}
|
||||||
|
|
||||||
void HahaNo(string no)
|
CommandResult HahaNo(string no)
|
||||||
{
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(no))
|
||||||
|
{
|
||||||
|
return new CommandResult(ResultType.InvalidInput, "fuck off");
|
||||||
|
}
|
||||||
|
|
||||||
Console.WriteLine($">>> {no.ToUpper()}");
|
Console.WriteLine($">>> {no.ToUpper()}");
|
||||||
|
|
||||||
|
return new CommandResult(ResultType.Success);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user