mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-07-05 03:58:16 +08:00
Implemented AddAsyncDelegate
(#766)
This commit is contained in:
@ -23,7 +23,7 @@ internal sealed class Configurator : IUnsafeConfigurator, IConfigurator, IConfig
|
||||
public void AddExample(params string[] args)
|
||||
{
|
||||
Examples.Add(args);
|
||||
}
|
||||
}
|
||||
|
||||
public ConfiguredCommand SetDefaultCommand<TDefaultCommand>()
|
||||
where TDefaultCommand : class, ICommand
|
||||
@ -42,6 +42,14 @@ internal sealed class Configurator : IUnsafeConfigurator, IConfigurator, IConfig
|
||||
|
||||
public ICommandConfigurator AddDelegate<TSettings>(string name, Func<CommandContext, TSettings, int> func)
|
||||
where TSettings : CommandSettings
|
||||
{
|
||||
var command = Commands.AddAndReturn(ConfiguredCommand.FromDelegate<TSettings>(
|
||||
name, (context, settings) => Task.FromResult(func(context, (TSettings)settings))));
|
||||
return new CommandConfigurator(command);
|
||||
}
|
||||
|
||||
public ICommandConfigurator AddAsyncDelegate<TSettings>(string name, Func<CommandContext, TSettings, Task<int>> func)
|
||||
where TSettings : CommandSettings
|
||||
{
|
||||
var command = Commands.AddAndReturn(ConfiguredCommand.FromDelegate<TSettings>(
|
||||
name, (context, settings) => func(context, (TSettings)settings)));
|
||||
|
@ -1,100 +1,111 @@
|
||||
namespace Spectre.Console.Cli;
|
||||
|
||||
internal sealed class Configurator<TSettings> : IUnsafeBranchConfigurator, IConfigurator<TSettings>
|
||||
where TSettings : CommandSettings
|
||||
{
|
||||
private readonly ConfiguredCommand _command;
|
||||
private readonly ITypeRegistrar? _registrar;
|
||||
|
||||
public Configurator(ConfiguredCommand command, ITypeRegistrar? registrar)
|
||||
{
|
||||
_command = command;
|
||||
_registrar = registrar;
|
||||
}
|
||||
|
||||
public void SetDescription(string description)
|
||||
{
|
||||
_command.Description = description;
|
||||
}
|
||||
|
||||
public void AddExample(string[] args)
|
||||
{
|
||||
_command.Examples.Add(args);
|
||||
}
|
||||
|
||||
public void SetDefaultCommand<TDefaultCommand>()
|
||||
where TDefaultCommand : class, ICommandLimiter<TSettings>
|
||||
{
|
||||
var defaultCommand = ConfiguredCommand.FromType<TDefaultCommand>(
|
||||
CliConstants.DefaultCommandName, isDefaultCommand: true);
|
||||
|
||||
_command.Children.Add(defaultCommand);
|
||||
}
|
||||
|
||||
public void HideBranch()
|
||||
{
|
||||
_command.IsHidden = true;
|
||||
}
|
||||
|
||||
public ICommandConfigurator AddCommand<TCommand>(string name)
|
||||
where TCommand : class, ICommandLimiter<TSettings>
|
||||
{
|
||||
var command = ConfiguredCommand.FromType<TCommand>(name, isDefaultCommand: false);
|
||||
var configurator = new CommandConfigurator(command);
|
||||
|
||||
_command.Children.Add(command);
|
||||
return configurator;
|
||||
}
|
||||
|
||||
public ICommandConfigurator AddDelegate<TDerivedSettings>(string name, Func<CommandContext, TDerivedSettings, int> func)
|
||||
where TDerivedSettings : TSettings
|
||||
{
|
||||
var command = ConfiguredCommand.FromDelegate<TDerivedSettings>(
|
||||
name, (context, settings) => func(context, (TDerivedSettings)settings));
|
||||
|
||||
_command.Children.Add(command);
|
||||
return new CommandConfigurator(command);
|
||||
}
|
||||
|
||||
public IBranchConfigurator AddBranch<TDerivedSettings>(string name, Action<IConfigurator<TDerivedSettings>> action)
|
||||
where TDerivedSettings : TSettings
|
||||
{
|
||||
var command = ConfiguredCommand.FromBranch<TDerivedSettings>(name);
|
||||
action(new Configurator<TDerivedSettings>(command, _registrar));
|
||||
var added = _command.Children.AddAndReturn(command);
|
||||
return new BranchConfigurator(added);
|
||||
}
|
||||
|
||||
ICommandConfigurator IUnsafeConfigurator.AddCommand(string name, Type command)
|
||||
{
|
||||
var method = GetType().GetMethod("AddCommand");
|
||||
if (method == null)
|
||||
{
|
||||
throw new CommandConfigurationException("Could not find AddCommand by reflection.");
|
||||
}
|
||||
|
||||
method = method.MakeGenericMethod(command);
|
||||
|
||||
if (!(method.Invoke(this, new object[] { name }) is ICommandConfigurator result))
|
||||
{
|
||||
throw new CommandConfigurationException("Invoking AddCommand returned null.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
IBranchConfigurator IUnsafeConfigurator.AddBranch(string name, Type settings, Action<IUnsafeBranchConfigurator> action)
|
||||
{
|
||||
var command = ConfiguredCommand.FromBranch(settings, name);
|
||||
|
||||
// Create the configurator.
|
||||
var configuratorType = typeof(Configurator<>).MakeGenericType(settings);
|
||||
if (!(Activator.CreateInstance(configuratorType, new object?[] { command, _registrar }) is IUnsafeBranchConfigurator configurator))
|
||||
{
|
||||
throw new CommandConfigurationException("Could not create configurator by reflection.");
|
||||
}
|
||||
|
||||
action(configurator);
|
||||
var added = _command.Children.AddAndReturn(command);
|
||||
return new BranchConfigurator(added);
|
||||
namespace Spectre.Console.Cli;
|
||||
|
||||
internal sealed class Configurator<TSettings> : IUnsafeBranchConfigurator, IConfigurator<TSettings>
|
||||
where TSettings : CommandSettings
|
||||
{
|
||||
private readonly ConfiguredCommand _command;
|
||||
private readonly ITypeRegistrar? _registrar;
|
||||
|
||||
public Configurator(ConfiguredCommand command, ITypeRegistrar? registrar)
|
||||
{
|
||||
_command = command;
|
||||
_registrar = registrar;
|
||||
}
|
||||
|
||||
public void SetDescription(string description)
|
||||
{
|
||||
_command.Description = description;
|
||||
}
|
||||
|
||||
public void AddExample(string[] args)
|
||||
{
|
||||
_command.Examples.Add(args);
|
||||
}
|
||||
|
||||
public void SetDefaultCommand<TDefaultCommand>()
|
||||
where TDefaultCommand : class, ICommandLimiter<TSettings>
|
||||
{
|
||||
var defaultCommand = ConfiguredCommand.FromType<TDefaultCommand>(
|
||||
CliConstants.DefaultCommandName, isDefaultCommand: true);
|
||||
|
||||
_command.Children.Add(defaultCommand);
|
||||
}
|
||||
|
||||
public void HideBranch()
|
||||
{
|
||||
_command.IsHidden = true;
|
||||
}
|
||||
|
||||
public ICommandConfigurator AddCommand<TCommand>(string name)
|
||||
where TCommand : class, ICommandLimiter<TSettings>
|
||||
{
|
||||
var command = ConfiguredCommand.FromType<TCommand>(name, isDefaultCommand: false);
|
||||
var configurator = new CommandConfigurator(command);
|
||||
|
||||
_command.Children.Add(command);
|
||||
return configurator;
|
||||
}
|
||||
|
||||
public ICommandConfigurator AddDelegate<TDerivedSettings>(string name, Func<CommandContext, TDerivedSettings, int> func)
|
||||
where TDerivedSettings : TSettings
|
||||
{
|
||||
var command = ConfiguredCommand.FromDelegate<TDerivedSettings>(
|
||||
name, (context, settings) => Task.FromResult(func(context, (TDerivedSettings)settings)));
|
||||
|
||||
_command.Children.Add(command);
|
||||
return new CommandConfigurator(command);
|
||||
}
|
||||
|
||||
public ICommandConfigurator AddAsyncDelegate<TDerivedSettings>(string name, Func<CommandContext, TDerivedSettings, Task<int>> func)
|
||||
where TDerivedSettings : TSettings
|
||||
{
|
||||
var command = ConfiguredCommand.FromDelegate<TDerivedSettings>(
|
||||
name, (context, settings) => func(context, (TDerivedSettings)settings));
|
||||
|
||||
_command.Children.Add(command);
|
||||
return new CommandConfigurator(command);
|
||||
}
|
||||
|
||||
public IBranchConfigurator AddBranch<TDerivedSettings>(string name, Action<IConfigurator<TDerivedSettings>> action)
|
||||
where TDerivedSettings : TSettings
|
||||
{
|
||||
var command = ConfiguredCommand.FromBranch<TDerivedSettings>(name);
|
||||
action(new Configurator<TDerivedSettings>(command, _registrar));
|
||||
var added = _command.Children.AddAndReturn(command);
|
||||
return new BranchConfigurator(added);
|
||||
}
|
||||
|
||||
ICommandConfigurator IUnsafeConfigurator.AddCommand(string name, Type command)
|
||||
{
|
||||
var method = GetType().GetMethod("AddCommand");
|
||||
if (method == null)
|
||||
{
|
||||
throw new CommandConfigurationException("Could not find AddCommand by reflection.");
|
||||
}
|
||||
|
||||
method = method.MakeGenericMethod(command);
|
||||
|
||||
if (!(method.Invoke(this, new object[] { name }) is ICommandConfigurator result))
|
||||
{
|
||||
throw new CommandConfigurationException("Invoking AddCommand returned null.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
IBranchConfigurator IUnsafeConfigurator.AddBranch(string name, Type settings, Action<IUnsafeBranchConfigurator> action)
|
||||
{
|
||||
var command = ConfiguredCommand.FromBranch(settings, name);
|
||||
|
||||
// Create the configurator.
|
||||
var configuratorType = typeof(Configurator<>).MakeGenericType(settings);
|
||||
if (!(Activator.CreateInstance(configuratorType, new object?[] { command, _registrar }) is IUnsafeBranchConfigurator configurator))
|
||||
{
|
||||
throw new CommandConfigurationException("Could not create configurator by reflection.");
|
||||
}
|
||||
|
||||
action(configurator);
|
||||
var added = _command.Children.AddAndReturn(command);
|
||||
return new BranchConfigurator(added);
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@ internal sealed class ConfiguredCommand
|
||||
public object? Data { get; set; }
|
||||
public Type? CommandType { get; }
|
||||
public Type SettingsType { get; }
|
||||
public Func<CommandContext, CommandSettings, int>? Delegate { get; }
|
||||
public Func<CommandContext, CommandSettings, Task<int>>? Delegate { get; }
|
||||
public bool IsDefaultCommand { get; }
|
||||
public bool IsHidden { get; set; }
|
||||
|
||||
@ -19,7 +19,7 @@ internal sealed class ConfiguredCommand
|
||||
string name,
|
||||
Type? commandType,
|
||||
Type settingsType,
|
||||
Func<CommandContext, CommandSettings, int>? @delegate,
|
||||
Func<CommandContext, CommandSettings, Task<int>>? @delegate,
|
||||
bool isDefaultCommand)
|
||||
{
|
||||
Name = name;
|
||||
@ -27,10 +27,10 @@ internal sealed class ConfiguredCommand
|
||||
CommandType = commandType;
|
||||
SettingsType = settingsType;
|
||||
Delegate = @delegate;
|
||||
IsDefaultCommand = isDefaultCommand;
|
||||
|
||||
IsDefaultCommand = isDefaultCommand;
|
||||
|
||||
// Default commands are always created as hidden.
|
||||
IsHidden = IsDefaultCommand;
|
||||
IsHidden = IsDefaultCommand;
|
||||
|
||||
Children = new List<ConfiguredCommand>();
|
||||
Examples = new List<string[]>();
|
||||
@ -60,8 +60,8 @@ internal sealed class ConfiguredCommand
|
||||
}
|
||||
|
||||
public static ConfiguredCommand FromDelegate<TSettings>(
|
||||
string name, Func<CommandContext, CommandSettings, int>? @delegate = null)
|
||||
where TSettings : CommandSettings
|
||||
string name, Func<CommandContext, CommandSettings, Task<int>>? @delegate = null)
|
||||
where TSettings : CommandSettings
|
||||
{
|
||||
return new ConfiguredCommand(name, null, typeof(TSettings), @delegate, false);
|
||||
}
|
||||
|
@ -2,16 +2,16 @@ namespace Spectre.Console.Cli;
|
||||
|
||||
internal sealed class DelegateCommand : ICommand
|
||||
{
|
||||
private readonly Func<CommandContext, CommandSettings, int> _func;
|
||||
private readonly Func<CommandContext, CommandSettings, Task<int>> _func;
|
||||
|
||||
public DelegateCommand(Func<CommandContext, CommandSettings, int> func)
|
||||
public DelegateCommand(Func<CommandContext, CommandSettings, Task<int>> func)
|
||||
{
|
||||
_func = func;
|
||||
}
|
||||
|
||||
public Task<int> Execute(CommandContext context, CommandSettings settings)
|
||||
{
|
||||
return Task.FromResult(_func(context, settings));
|
||||
return _func(context, settings);
|
||||
}
|
||||
|
||||
public ValidationResult Validate(CommandContext context, CommandSettings settings)
|
||||
|
@ -1,14 +1,14 @@
|
||||
namespace Spectre.Console.Cli;
|
||||
|
||||
internal sealed class CommandInfo : ICommandContainer
|
||||
{
|
||||
{
|
||||
public string Name { get; }
|
||||
public HashSet<string> Aliases { get; }
|
||||
public string? Description { get; }
|
||||
public object? Data { get; }
|
||||
public Type? CommandType { get; }
|
||||
public Type SettingsType { get; }
|
||||
public Func<CommandContext, CommandSettings, int>? Delegate { get; }
|
||||
public Func<CommandContext, CommandSettings, Task<int>>? Delegate { get; }
|
||||
public bool IsDefaultCommand { get; }
|
||||
public CommandInfo? Parent { get; }
|
||||
public IList<CommandInfo> Children { get; }
|
||||
@ -16,11 +16,11 @@ internal sealed class CommandInfo : ICommandContainer
|
||||
public IList<string[]> Examples { get; }
|
||||
|
||||
public bool IsBranch => CommandType == null && Delegate == null;
|
||||
IList<CommandInfo> ICommandContainer.Commands => Children;
|
||||
|
||||
IList<CommandInfo> ICommandContainer.Commands => Children;
|
||||
|
||||
// only branches can have a default command
|
||||
public CommandInfo? DefaultCommand => IsBranch ? Children.FirstOrDefault(c => c.IsDefaultCommand) : null;
|
||||
public bool IsHidden { get; }
|
||||
public CommandInfo? DefaultCommand => IsBranch ? Children.FirstOrDefault(c => c.IsDefaultCommand) : null;
|
||||
public bool IsHidden { get; }
|
||||
|
||||
public CommandInfo(CommandInfo? parent, ConfiguredCommand prototype)
|
||||
{
|
||||
|
Reference in New Issue
Block a user