diff --git a/src/Discord.Net.Commands/Command.cs b/src/Discord.Net.Commands/Command.cs index 50f958ba2..bc1013245 100644 --- a/src/Discord.Net.Commands/Command.cs +++ b/src/Discord.Net.Commands/Command.cs @@ -4,17 +4,26 @@ using System.Threading.Tasks; namespace Discord.Commands { + public enum ParameterType + { + /// Catches a single required parameter. + Required, + /// Catches a single optional parameter. + Optional, + /// Catches a zero or more optional parameters. + Multiple, + /// Catches all remaining text as a single optional parameter. + Unparsed + } public sealed class CommandParameter { public string Name { get; } - public bool IsOptional { get; } - public bool IsCatchAll { get; } + public ParameterType Type { get; } - public CommandParameter(string name, bool isOptional, bool isCatchAll) + public CommandParameter(string name, ParameterType type) { Name = name; - IsOptional = isOptional; - IsCatchAll = isCatchAll; + Type = type; } } @@ -60,7 +69,7 @@ namespace Discord.Commands } else { - if (parameters[parameters.Length - 1].IsCatchAll) + if (parameters[parameters.Length - 1].Type == ParameterType.Multiple) MaxArgs = null; else MaxArgs = parameters.Length; @@ -68,7 +77,7 @@ namespace Discord.Commands int? optionalStart = null; for (int i = parameters.Length - 1; i >= 0; i--) { - if (parameters[i].IsOptional) + if (parameters[i].Type == ParameterType.Optional) optionalStart = i; else break; diff --git a/src/Discord.Net.Commands/CommandBuilder.cs b/src/Discord.Net.Commands/CommandBuilder.cs index a97ff8d73..e0b4a5d54 100644 --- a/src/Discord.Net.Commands/CommandBuilder.cs +++ b/src/Discord.Net.Commands/CommandBuilder.cs @@ -10,7 +10,7 @@ namespace Discord.Commands private readonly CommandsPlugin _plugin; private readonly Command _command; private List _params; - private bool _hasOptional, _hasCatchAll; + private bool _allowRequired, _isClosed; private string _prefix; public CommandBuilder(CommandsPlugin plugin, Command command, string prefix) @@ -19,6 +19,8 @@ namespace Discord.Commands _command = command; _params = new List(); _prefix = prefix; + _allowRequired = true; + _isClosed = false; } public CommandBuilder Alias(params string[] aliases) @@ -32,19 +34,19 @@ namespace Discord.Commands _command.Description = description; return this; } - public CommandBuilder Parameter(string name, bool isOptional = false, bool isCatchAll = false) + public CommandBuilder Parameter(string name, ParameterType type = ParameterType.Required) { - if (_hasCatchAll) - throw new Exception("No parameters may be added after the catch-all"); - if (_hasOptional && !isOptional) - throw new Exception("Non-optional parameters may not be added after an optional one"); + if (_isClosed) + throw new Exception($"No parameters may be added after a {nameof(ParameterType.Multiple)} or {nameof(ParameterType.Unparsed)} parameter."); + if (!_allowRequired && type != ParameterType.Required) + throw new Exception($"{nameof(ParameterType.Required)} parameters may not be added after an optional one"); - _params.Add(new CommandParameter(name, isOptional, isCatchAll)); + _params.Add(new CommandParameter(name, type)); - if (isOptional) - _hasOptional = true; - if (isCatchAll) - _hasCatchAll = true; + if (type == ParameterType.Optional) + _allowRequired = false; + if (type == ParameterType.Multiple || type == ParameterType.Unparsed) + _isClosed = true; return this; } public CommandBuilder IsHidden() diff --git a/src/Discord.Net.Commands/CommandsPlugin.cs b/src/Discord.Net.Commands/CommandsPlugin.cs index f15664348..f34bbbfe1 100644 --- a/src/Discord.Net.Commands/CommandsPlugin.cs +++ b/src/Discord.Net.Commands/CommandsPlugin.cs @@ -41,7 +41,7 @@ namespace Discord.Commands if (builtInHelp) { CreateCommand("help") - .Parameter("command", isOptional: true) + .Parameter("command", ParameterType.Optional) .IsHidden() .Info("Returns information about commands.") .Do(async e =>