namespace Spectre.Console.Cli; internal sealed class Configurator : IUnsafeConfigurator, IConfigurator, IConfiguration { private readonly ITypeRegistrar _registrar; public IList Commands { get; } public CommandAppSettings Settings { get; } public ConfiguredCommand? DefaultCommand { get; private set; } public IList Examples { get; } ICommandAppSettings IConfigurator.Settings => Settings; public Configurator(ITypeRegistrar registrar) { _registrar = registrar; Commands = new List(); Settings = new CommandAppSettings(registrar); Examples = new List(); } public void AddExample(string[] args) { Examples.Add(args); } public ConfiguredCommand SetDefaultCommand() where TDefaultCommand : class, ICommand { DefaultCommand = ConfiguredCommand.FromType( CliConstants.DefaultCommandName, isDefaultCommand: true); return DefaultCommand; } public ICommandConfigurator AddCommand(string name) where TCommand : class, ICommand { var command = Commands.AddAndReturn(ConfiguredCommand.FromType(name, false)); return new CommandConfigurator(command); } public ICommandConfigurator AddDelegate(string name, Func func) where TSettings : CommandSettings { var command = Commands.AddAndReturn(ConfiguredCommand.FromDelegate( name, (context, settings) => func(context, (TSettings)settings))); return new CommandConfigurator(command); } public IBranchConfigurator AddBranch(string name, Action> action) where TSettings : CommandSettings { var command = ConfiguredCommand.FromBranch(name); action(new Configurator(command, _registrar)); var added = Commands.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 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 = Commands.AddAndReturn(command); return new BranchConfigurator(added); } }