Skip to content
This repository has been archived by the owner on Dec 12, 2024. It is now read-only.

Commit

Permalink
Feat: Working Async methods & params
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreasSasDev committed Apr 28, 2024
1 parent b388571 commit b0a9a20
Show file tree
Hide file tree
Showing 11 changed files with 52 additions and 37 deletions.
6 changes: 3 additions & 3 deletions examples/CliArgsParser.Examples.RegisterAtlas/ArgsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
// ---------------------------------------------------------------------------------------------------------------------

using CliArgsParser.Attributes;
using CliArgsParser.Contracts;

namespace CliArgsParser.Examples.RegisterAtlas;

// ---------------------------------------------------------------------------------------------------------------------
// Code
// ---------------------------------------------------------------------------------------------------------------------
[Parameters]
public class ArgsTest {
[AutoArgFlag("username")] public string Username { get; set; } = "undefined";
public class ArgsTest : IParameters {
[AutoArgValue("username")]public string Username { get; set; } = "undefined";
}
9 changes: 7 additions & 2 deletions examples/CliArgsParser.Examples.RegisterAtlas/HelloAtlas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ public async Task CommmandHelloAsync() {
}

[Command<ArgsTest>("hello-test")]
public void CommmandHelloAsyncArgsTest(ArgsTest argsTest) {
// await Task.Delay(100);
public void CommmandTestArgs(ArgsTest argsTest) {
Console.WriteLine($"IT WORKS! & with args : {argsTest.Username}");
}

[Command<ArgsTest>("hello-test-async")]
public async Task CommmandTestArgsAsync(ArgsTest argsTest) {
await Task.Delay(100);
Console.WriteLine($"IT WORKS! in ASYNC & with args : {argsTest.Username}");
}
}
5 changes: 4 additions & 1 deletion examples/CliArgsParser.Examples.RegisterAtlas/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ namespace CliArgsParser.Examples.RegisterAtlas;
// ---------------------------------------------------------------------------------------------------------------------
static class Program {
public static async Task MainAsync(IParser parser, string[] args) {
await parser.TryParseAsync("hello && hello-async && hello-test --username=andreas");
// await parser.TryParseAsync("hello");
// await parser.TryParseAsync("hello-async ");
// await parser.TryParseAsync("""hello-test --username="andreas" """);
await parser.TryParseAsync("hello-test-async --username=andreas");
}

public static void Main(string[] args) {
Expand Down
3 changes: 2 additions & 1 deletion src/CliArgsParser.Contracts/IParameterParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ namespace CliArgsParser.Contracts;
// Code
// ---------------------------------------------------------------------------------------------------------------------
public interface IParameterParser {
public object? Parse(Dictionary<string, string>? args);
public Type ParamsType { get; }
public IParameters? Parse(Dictionary<string, string>? args);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
// Imports
// ---------------------------------------------------------------------------------------------------------------------

namespace CliArgsParser.Attributes;
namespace CliArgsParser.Contracts;

// ---------------------------------------------------------------------------------------------------------------------
// Code
// ---------------------------------------------------------------------------------------------------------------------
[AttributeUsage(AttributeTargets.Class)]
public class ParametersAttribute : Attribute {

public interface IParameters {

}
6 changes: 3 additions & 3 deletions src/CliArgsParser/CommandMethodInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ public static Delegate GetDelegate(MethodInfo info, object atlas, ILogger logger
try {
switch (info.GetParameters().Length) {
// Method is async and has parameters
case > 1 when isAsync && parameterType != typeof(NoArgs): {
case >= 1 when isAsync && parameterType != typeof(NoArgs): {
Type delegateType = typeof(Func<,>).MakeGenericType(parameterType, typeof(Task));
commandDelegate = Delegate.CreateDelegate(delegateType, atlas, info);
logger.Debug("Created a delegate of type: {delegateType}", delegateType.Name);
break;
}

// If method is non-async action and has parameters
case > 1 when !isAsync && parameterType != typeof(NoArgs): {
case >= 1 when !isAsync && parameterType != typeof(NoArgs): {
Type delegateType = typeof(Action<>).MakeGenericType(parameterType);
commandDelegate = Delegate.CreateDelegate(delegateType, atlas, info);
logger.Debug("Created a delegate of type: {delegateType}", delegateType.Name);
Expand Down Expand Up @@ -78,7 +78,7 @@ public static Delegate GetDelegate(MethodInfo info, object atlas, ILogger logger

return commandDelegate;
}

private static IParameterParser CreateParameterParser(MethodInfo info) {
return new ParameterParser(GetCommandAttribute(info)?.ArgsType ?? typeof(NoArgs));
}
Expand Down
12 changes: 5 additions & 7 deletions src/CliArgsParser/ParameterParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// Imports
// ---------------------------------------------------------------------------------------------------------------------
using System.Reflection;
using CliArgsParser.Attributes;
using CliArgsParser.Contracts;
using CliArgsParser.Contracts.Attributes;

Expand All @@ -16,13 +15,13 @@ public class ParameterParser : IParameterParser {
private readonly Dictionary<string, PropertyInfo> _valueProperties = new();
private readonly Dictionary<string, PropertyInfo> _flagProperties = new();

private Type _type;
public Type ParamsType { get; private set; }

// -----------------------------------------------------------------------------------------------------------------
// Methods
// -----------------------------------------------------------------------------------------------------------------
public ParameterParser(Type type) {
_type = type;
ParamsType = type;
PropertyInfo[] propertyInfos = type.GetProperties(BindingFlags.Public | BindingFlags.Instance );

foreach (PropertyInfo? prop in propertyInfos) {
Expand All @@ -44,10 +43,9 @@ public ParameterParser(Type type) {
/// </summary>
/// <param name="args">The command-line arguments.</param>
/// <returns>An instance of the specified parameter options type.</returns>
public object? Parse(Dictionary<string, string>? args) {
object? result = Activator.CreateInstance(_type);

if (args == null) {
public IParameters? Parse(Dictionary<string, string>? args) {
IParameters? result = (IParameters?)Activator.CreateInstance(ParamsType);
if (result == null) {
return result;
}

Expand Down
4 changes: 2 additions & 2 deletions src/CliArgsParser/PreMade/Args/ForceArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
// ---------------------------------------------------------------------------------------------------------------------

using CliArgsParser.Attributes;
using CliArgsParser.Contracts;

namespace CliArgsParser.PreMade.Args;

// ---------------------------------------------------------------------------------------------------------------------
// Code
// ---------------------------------------------------------------------------------------------------------------------
[Parameters]
public class ForceArgs {
public class ForceArgs : IParameters {
[ArgFlag("force", "Forces stuff")] public bool IsForced { get; set; } = false;
}
6 changes: 2 additions & 4 deletions src/CliArgsParser/PreMade/Args/NoArgs.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
// ---------------------------------------------------------------------------------------------------------------------
// Imports
// ---------------------------------------------------------------------------------------------------------------------

using CliArgsParser.Attributes;
using CliArgsParser.Contracts;

namespace CliArgsParser.PreMade.Args;

// ---------------------------------------------------------------------------------------------------------------------
// Code
// ---------------------------------------------------------------------------------------------------------------------
[Parameters]
public class NoArgs {
public class NoArgs : IParameters{

}
8 changes: 4 additions & 4 deletions src/CliArgsParser/PreMade/Parsers/AbstractParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ public Dictionary<string, string> GetArgs(string argsInput) {
.Matches(argsInput)
.Where(match => match.Success)
.ToDictionary(
match => match.Groups[1].Value,
match => match.Groups[2].Success
? match.Groups[2].Value.Trim('"')
match => match.Groups[2].Value,
match => match.Groups[3].Success
? match.Groups[3].Value.Trim('"')
: "True"
);
}
Expand Down Expand Up @@ -69,7 +69,7 @@ public IEnumerable<string> GetCommands(string input) {
.Select(s => s.Trim());
}

[GeneratedRegex("""(--|-)(\w+)(=\"[^\"]*\"|\w*)?""")]
[GeneratedRegex("""(--|-)(\w+)(?:=(\"[^\"]*\"|\w*))?""")]
public static partial Regex ArgsRegex();

[GeneratedRegex("""&&(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)""")]
Expand Down
24 changes: 17 additions & 7 deletions src/CliArgsParser/PreMade/Parsers/ArgsParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Imports
// ---------------------------------------------------------------------------------------------------------------------

using CliArgsParser.Contracts;
using CliArgsParser.Contracts.Common;
using CliArgsParser.PreMade.Args;

Expand All @@ -24,7 +25,8 @@ public class ArgsParser : AbstractParser {
}

try {
object? parameters = commandRecord.ParameterParser.Parse(args);
var parameters = commandRecord.ParameterParser.Parse(args);

if(parameters?.GetType() == typeof(NoArgs)) {
output = (T)commandRecord.Delegate.DynamicInvoke()!;
return true;
Expand Down Expand Up @@ -66,11 +68,16 @@ public override async Task<bool> TryParseAsync(string input) {
}

try {
Log.Debug($"Parsing parameters for command: {commandName}");
object? parameters = commandRecord?.ParameterParser.Parse(args);

Log.Debug("Parsing parameters for command: {name}",commandName);

IParameters? parameters = commandRecord.ParameterParser.Parse(args);

Log.Debug("Found params : {@params}", parameters);

if (parameters?.GetType() == typeof(NoArgs)) {
Log.Debug($"Command: {commandName} has no parameters.");
if (commandRecord?.Delegate is Func<Task> func) {
if (commandRecord.Delegate is Func<Task> func) {
Log.Debug("Invoking async delegate without parameters.");
await func(); // For Async methods without parameters
continue;
Expand All @@ -81,14 +88,17 @@ public override async Task<bool> TryParseAsync(string input) {
continue;
}
}
if (commandRecord.Delegate is Func<object?, Task> funcWithParam) {

Log.Debug("{@a}", commandRecord?.Delegate?.Method);
if (commandRecord is { IsAsync: true }) {
Log.Debug("Invoking async delegate with parameters.");
await funcWithParam(parameters); // For Async methods with parameters
var task = (Task)commandRecord.Delegate?.DynamicInvoke(parameters)!;
await task;
continue;
}

Log.Debug("Invoking synchronous delegate with parameters.");
commandRecord.Delegate.DynamicInvoke(parameters); // For non-async methods with parameters
commandRecord?.Delegate?.DynamicInvoke(parameters); // For non-async methods with parameters
}
catch (Exception e) {
Log.Error(e, "Error occurred during command execution.");
Expand Down

0 comments on commit b0a9a20

Please sign in to comment.