Browse Source

Add requested changes

Changes:
- Use IResult instead of Optional CommandMatch

- Rework branching workflow
tags/3.0.0
roridev 3 years ago
parent
commit
a92ec56d88
No known key found for this signature in database GPG Key ID: D3A399A927942715
1 changed files with 36 additions and 19 deletions
  1. +36
    -19
      src/Discord.Net.Commands/CommandService.cs

+ 36
- 19
src/Discord.Net.Commands/CommandService.cs View File

@@ -507,27 +507,44 @@ namespace Discord.Commands

var searchResult = Search(input);

//Since ValidateAndGetBestMatch is deterministic on the return type, we can use pattern matching on the type for infering the code flow.
var (validationResult, commandMatch) = await ValidateAndGetBestMatch(searchResult, context, services, multiMatchHandling);
var validationResult = await ValidateAndGetBestMatch(searchResult, context, services, multiMatchHandling);

if(validationResult is SearchResult)
if (validationResult is SearchResult result)
{
await _commandExecutedEvent.InvokeAsync(Optional.Create<CommandInfo>(), context, searchResult).ConfigureAwait(false);
}
else if(validationResult is ParseResult parseResult)
{
var result = await commandMatch.Value.Command.ExecuteAsync(context, parseResult, services).ConfigureAwait(false);
if (!result.IsSuccess && !(result is RuntimeResult || result is ExecuteResult)) // succesful results raise the event in CommandInfo#ExecuteInternalAsync (have to raise it there b/c deffered execution)
await _commandExecutedEvent.InvokeAsync(commandMatch.Value.Command, context, result);
await _commandExecutedEvent.InvokeAsync(Optional.Create<CommandInfo>(), context, result).ConfigureAwait(false);
return result;
}
else

if (validationResult is MatchResult matchResult)
{
await _commandExecutedEvent.InvokeAsync(commandMatch.Value.Command, context, validationResult).ConfigureAwait(false);
return await handleCommandPipeline(matchResult, context, services);
}

return validationResult;
}

private async Task<IResult> handleCommandPipeline(MatchResult matchResult, ICommandContext context, IServiceProvider services)
{
if (!matchResult.IsSuccess)
return matchResult;

if (matchResult.Pipeline is ParseResult parseResult)
{
var executeResult = await matchResult.Match.Value.ExecuteAsync(context, parseResult, services);

if (!executeResult.IsSuccess && !(executeResult is RuntimeResult || executeResult is ExecuteResult)) // succesful results raise the event in CommandInfo#ExecuteInternalAsync (have to raise it there b/c deffered execution)
await _commandExecutedEvent.InvokeAsync(matchResult.Match.Value.Command, context, executeResult);
return executeResult;
}

if (matchResult.Pipeline is PreconditionResult preconditionResult)
{
await _commandExecutedEvent.InvokeAsync(matchResult.Match.Value.Command, context, preconditionResult).ConfigureAwait(false);
}

return matchResult;
}

// Calculates the 'score' of a command given a parse result
float CalculateScore(CommandMatch match, ParseResult parseResult)
{
@@ -554,11 +571,11 @@ namespace Discord.Commands
/// <param name="provider">The service provider to be used on the command's dependency injection.</param>
/// <param name="multiMatchHandling">The handling mode when multiple command matches are found.</param>
/// <returns>A task that represents the asynchronous validation operation. The task result contains the result of the
/// command validation and the command matched, if a match was found.</returns>
public async Task<(IResult, Optional<CommandMatch>)> ValidateAndGetBestMatch(SearchResult matches, ICommandContext context, IServiceProvider provider, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception)
/// command validation as a <see cref="MatchResult"/> or a <see cref="SearchResult"/> if no matches were found.</returns>
public async Task<IResult> ValidateAndGetBestMatch(SearchResult matches, ICommandContext context, IServiceProvider provider, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception)
{
if (!matches.IsSuccess)
return (matches, Optional.Create<CommandMatch>());
return matches;

var commands = matches.Commands;
var preconditionResults = new Dictionary<CommandMatch, PreconditionResult>();
@@ -574,11 +591,11 @@ namespace Discord.Commands

if (successfulPreconditions.Length == 0)
{
//All preconditions failed, return the one from the highest priority command
var bestCandidate = preconditionResults
.OrderByDescending(x => x.Key.Command.Priority)
.FirstOrDefault(x => !x.Value.IsSuccess);

return (bestCandidate.Value, bestCandidate.Key);
return MatchResult.FromSuccess(bestCandidate.Key,bestCandidate.Value);
}

var parseResults = new Dictionary<CommandMatch, ParseResult>();
@@ -615,12 +632,12 @@ namespace Discord.Commands
var bestMatch = parseResults
.FirstOrDefault(x => !x.Value.IsSuccess);

return (bestMatch.Value, bestMatch.Key);
return MatchResult.FromSuccess(bestMatch.Key,bestMatch.Value);
}

var chosenOverload = successfulParses[0];

return (chosenOverload.Value, chosenOverload.Key);
return MatchResult.FromSuccess(chosenOverload.Key,chosenOverload.Value);
}

protected virtual void Dispose(bool disposing)


Loading…
Cancel
Save