Add grouping of preconditions to allow for flexible precondition logic. (#672)
* Add grouping of preconditions to allow for flexible precondition logic. * Fix checking Module Preconditions twice (and none of the command's own) * Fix command preconditions group 0 looping over every other precondition anyway #whoopsies * Use custom message when a non-zero Precondition Group fails. * Fix doc comment rendering. * Refactor loops into local function * Considering a new result type * Switch to IReadOnlyCollection<T> and fix compiler errors * Revert PreconditionResult -> IResult in return types - Change PreconditionResult to a class that PreconditionGroupResult inherits. * Feedback on property name. * Change grouping type int -> string * Explicitly use an ordinal StringComparer * Full stops on error messages * Remove some sillyness. * Remove unneeded using.
This commit is contained in:
@@ -68,29 +68,49 @@ namespace Discord.Commands
|
||||
{
|
||||
services = services ?? EmptyServiceProvider.Instance;
|
||||
|
||||
foreach (PreconditionAttribute precondition in Module.Preconditions)
|
||||
async Task<PreconditionGroupResult> CheckGroups(IEnumerable<PreconditionAttribute> preconditions, string type)
|
||||
{
|
||||
var result = await precondition.CheckPermissions(context, this, services).ConfigureAwait(false);
|
||||
if (!result.IsSuccess)
|
||||
return result;
|
||||
foreach (IGrouping<string, PreconditionAttribute> preconditionGroup in preconditions.GroupBy(p => p.Group, StringComparer.Ordinal))
|
||||
{
|
||||
if (preconditionGroup.Key == null)
|
||||
{
|
||||
foreach (PreconditionAttribute precondition in preconditionGroup)
|
||||
{
|
||||
var result = await precondition.CheckPermissions(context, this, services).ConfigureAwait(false);
|
||||
if (!result.IsSuccess)
|
||||
return PreconditionGroupResult.FromError($"{type} default precondition group failed.", new[] { result });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var results = new List<PreconditionResult>();
|
||||
foreach (PreconditionAttribute precondition in preconditionGroup)
|
||||
results.Add(await precondition.CheckPermissions(context, this, services).ConfigureAwait(false));
|
||||
|
||||
if (!results.Any(p => p.IsSuccess))
|
||||
return PreconditionGroupResult.FromError($"{type} precondition group {preconditionGroup.Key} failed.", results);
|
||||
}
|
||||
}
|
||||
return PreconditionGroupResult.FromSuccess();
|
||||
}
|
||||
|
||||
foreach (PreconditionAttribute precondition in Preconditions)
|
||||
{
|
||||
var result = await precondition.CheckPermissions(context, this, services).ConfigureAwait(false);
|
||||
if (!result.IsSuccess)
|
||||
return result;
|
||||
}
|
||||
var moduleResult = await CheckGroups(Module.Preconditions, "Module");
|
||||
if (!moduleResult.IsSuccess)
|
||||
return moduleResult;
|
||||
|
||||
var commandResult = await CheckGroups(Preconditions, "Command");
|
||||
if (!commandResult.IsSuccess)
|
||||
return commandResult;
|
||||
|
||||
return PreconditionResult.FromSuccess();
|
||||
}
|
||||
|
||||
public async Task<ParseResult> ParseAsync(ICommandContext context, int startIndex, SearchResult searchResult, PreconditionResult? preconditionResult = null)
|
||||
public async Task<ParseResult> ParseAsync(ICommandContext context, int startIndex, SearchResult searchResult, PreconditionResult preconditionResult = null)
|
||||
{
|
||||
if (!searchResult.IsSuccess)
|
||||
return ParseResult.FromError(searchResult);
|
||||
if (preconditionResult != null && !preconditionResult.Value.IsSuccess)
|
||||
return ParseResult.FromError(preconditionResult.Value);
|
||||
if (preconditionResult != null && !preconditionResult.IsSuccess)
|
||||
return ParseResult.FromError(preconditionResult);
|
||||
|
||||
string input = searchResult.Text.Substring(startIndex);
|
||||
return await CommandParser.ParseArgs(this, context, input, 0).ConfigureAwait(false);
|
||||
|
||||
Reference in New Issue
Block a user