| @@ -67,7 +67,7 @@ namespace Discord.Commands | |||||
| return PreconditionResult.FromError($"Command requires channel permission {ChannelPermission.Value}"); | return PreconditionResult.FromError($"Command requires channel permission {ChannelPermission.Value}"); | ||||
| } | } | ||||
| return PreconditionResult.FromSuccess(); | |||||
| return PreconditionResult.Success; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -49,7 +49,7 @@ namespace Discord.Commands | |||||
| isValid = isValid || context.Channel is IGroupChannel; | isValid = isValid || context.Channel is IGroupChannel; | ||||
| if (isValid) | if (isValid) | ||||
| return Task.FromResult(PreconditionResult.FromSuccess()); | |||||
| return Task.FromResult(PreconditionResult.Success); | |||||
| else | else | ||||
| return Task.FromResult(PreconditionResult.FromError($"Invalid context for command; accepted contexts: {Contexts}")); | return Task.FromResult(PreconditionResult.FromError($"Invalid context for command; accepted contexts: {Contexts}")); | ||||
| } | } | ||||
| @@ -18,11 +18,11 @@ namespace Discord.Commands | |||||
| var application = await context.Client.GetApplicationInfoAsync(); | var application = await context.Client.GetApplicationInfoAsync(); | ||||
| if (context.User.Id != application.Owner.Id) | if (context.User.Id != application.Owner.Id) | ||||
| return PreconditionResult.FromError("Command can only be run by the owner of the bot"); | return PreconditionResult.FromError("Command can only be run by the owner of the bot"); | ||||
| return PreconditionResult.FromSuccess(); | |||||
| return PreconditionResult.Success; | |||||
| case TokenType.User: | case TokenType.User: | ||||
| if (context.User.Id != context.Client.CurrentUser.Id) | if (context.User.Id != context.Client.CurrentUser.Id) | ||||
| return PreconditionResult.FromError("Command can only be run by the owner of the bot"); | return PreconditionResult.FromError("Command can only be run by the owner of the bot"); | ||||
| return PreconditionResult.FromSuccess(); | |||||
| return PreconditionResult.Success; | |||||
| default: | default: | ||||
| return PreconditionResult.FromError($"{nameof(RequireOwnerAttribute)} is not supported by this {nameof(TokenType)}."); | return PreconditionResult.FromError($"{nameof(RequireOwnerAttribute)} is not supported by this {nameof(TokenType)}."); | ||||
| } | } | ||||
| @@ -68,7 +68,7 @@ namespace Discord.Commands | |||||
| return Task.FromResult(PreconditionResult.FromError($"Command requires channel permission {ChannelPermission.Value}")); | return Task.FromResult(PreconditionResult.FromError($"Command requires channel permission {ChannelPermission.Value}")); | ||||
| } | } | ||||
| return Task.FromResult(PreconditionResult.FromSuccess()); | |||||
| return Task.FromResult(PreconditionResult.Success); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -16,11 +16,11 @@ namespace Discord.Commands | |||||
| public Task<PreconditionResult> CheckPreconditionsAsync(ICommandContext context, IDependencyMap map = null) | public Task<PreconditionResult> CheckPreconditionsAsync(ICommandContext context, IDependencyMap map = null) | ||||
| => Command.CheckPreconditionsAsync(context, map); | => Command.CheckPreconditionsAsync(context, map); | ||||
| public Task<ParseResult> ParseAsync(ICommandContext context, SearchResult searchResult, PreconditionResult preconditionResult = null) | |||||
| => Command.ParseAsync(context, Alias.Length, searchResult, preconditionResult); | |||||
| public Task<ExecuteResult> ExecuteAsync(ICommandContext context, IEnumerable<object> argList, IEnumerable<object> paramList, IDependencyMap map) | |||||
| public Task<ParseResult> ParseAsync(ICommandContext context, SearchResult searchResult) | |||||
| => Command.ParseAsync(context, searchResult.Text.Substring(Alias.Length)); | |||||
| public Task<IResult> ExecuteAsync(ICommandContext context, IEnumerable<object> argList, IEnumerable<object> paramList, IDependencyMap map) | |||||
| => Command.ExecuteAsync(context, argList, paramList, map); | => Command.ExecuteAsync(context, argList, paramList, map); | ||||
| public Task<ExecuteResult> ExecuteAsync(ICommandContext context, ParseResult parseResult, IDependencyMap map) | |||||
| public Task<IResult> ExecuteAsync(ICommandContext context, ParseResult parseResult, IDependencyMap map) | |||||
| => Command.ExecuteAsync(context, parseResult, map); | => Command.ExecuteAsync(context, parseResult, map); | ||||
| } | } | ||||
| } | } | ||||
| @@ -112,7 +112,7 @@ namespace Discord.Commands | |||||
| var typeReaderResult = await curParam.Parse(context, argString).ConfigureAwait(false); | var typeReaderResult = await curParam.Parse(context, argString).ConfigureAwait(false); | ||||
| if (!typeReaderResult.IsSuccess && typeReaderResult.Error != CommandError.MultipleMatches) | if (!typeReaderResult.IsSuccess && typeReaderResult.Error != CommandError.MultipleMatches) | ||||
| return ParseResult.FromError(typeReaderResult); | |||||
| return ParseResult.FromTypeReaderResult(typeReaderResult); | |||||
| if (curParam.IsMultiple) | if (curParam.IsMultiple) | ||||
| { | { | ||||
| @@ -135,7 +135,7 @@ namespace Discord.Commands | |||||
| { | { | ||||
| var typeReaderResult = await curParam.Parse(context, argBuilder.ToString()).ConfigureAwait(false); | var typeReaderResult = await curParam.Parse(context, argBuilder.ToString()).ConfigureAwait(false); | ||||
| if (!typeReaderResult.IsSuccess) | if (!typeReaderResult.IsSuccess) | ||||
| return ParseResult.FromError(typeReaderResult); | |||||
| return ParseResult.FromTypeReaderResult(typeReaderResult); | |||||
| argList.Add(typeReaderResult); | argList.Add(typeReaderResult); | ||||
| } | } | ||||
| @@ -261,13 +261,13 @@ namespace Discord.Commands | |||||
| var preconditionResult = await commands[i].CheckPreconditionsAsync(context, dependencyMap).ConfigureAwait(false); | var preconditionResult = await commands[i].CheckPreconditionsAsync(context, dependencyMap).ConfigureAwait(false); | ||||
| if (!preconditionResult.IsSuccess) | if (!preconditionResult.IsSuccess) | ||||
| { | { | ||||
| if (commands.Count == 1) | |||||
| if (i == commands.Count) | |||||
| return preconditionResult; | return preconditionResult; | ||||
| else | else | ||||
| continue; | continue; | ||||
| } | } | ||||
| var parseResult = await commands[i].ParseAsync(context, searchResult, preconditionResult).ConfigureAwait(false); | |||||
| var parseResult = await commands[i].ParseAsync(context, searchResult).ConfigureAwait(false); | |||||
| if (!parseResult.IsSuccess) | if (!parseResult.IsSuccess) | ||||
| { | { | ||||
| if (parseResult.Error == CommandError.MultipleMatches) | if (parseResult.Error == CommandError.MultipleMatches) | ||||
| @@ -285,7 +285,7 @@ namespace Discord.Commands | |||||
| if (!parseResult.IsSuccess) | if (!parseResult.IsSuccess) | ||||
| { | { | ||||
| if (commands.Count == 1) | |||||
| if (i == commands.Count) | |||||
| return parseResult; | return parseResult; | ||||
| else | else | ||||
| continue; | continue; | ||||
| @@ -82,30 +82,21 @@ namespace Discord.Commands | |||||
| return result; | return result; | ||||
| } | } | ||||
| return PreconditionResult.FromSuccess(); | |||||
| return PreconditionResult.Success; | |||||
| } | } | ||||
| public async Task<ParseResult> ParseAsync(ICommandContext context, int startIndex, SearchResult searchResult, PreconditionResult preconditionResult = null) | |||||
| public async Task<ParseResult> ParseAsync(ICommandContext context, string input) | |||||
| { | { | ||||
| if (!searchResult.IsSuccess) | |||||
| return ParseResult.FromError(searchResult); | |||||
| 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); | return await CommandParser.ParseArgs(this, context, input, 0).ConfigureAwait(false); | ||||
| } | } | ||||
| public Task<ExecuteResult> ExecuteAsync(ICommandContext context, ParseResult parseResult, IDependencyMap map) | |||||
| public Task<IResult> ExecuteAsync(ICommandContext context, ParseResult parseResult, IDependencyMap map) | |||||
| { | { | ||||
| if (!parseResult.IsSuccess) | |||||
| return Task.FromResult(ExecuteResult.FromError(parseResult)); | |||||
| var argList = new object[parseResult.ArgValues.Count]; | var argList = new object[parseResult.ArgValues.Count]; | ||||
| for (int i = 0; i < parseResult.ArgValues.Count; i++) | for (int i = 0; i < parseResult.ArgValues.Count; i++) | ||||
| { | { | ||||
| if (!parseResult.ArgValues[i].IsSuccess) | if (!parseResult.ArgValues[i].IsSuccess) | ||||
| return Task.FromResult(ExecuteResult.FromError(parseResult.ArgValues[i])); | |||||
| return Task.FromResult(parseResult.ArgValues[i] as IResult); | |||||
| argList[i] = parseResult.ArgValues[i].Values.First().Value; | argList[i] = parseResult.ArgValues[i].Values.First().Value; | ||||
| } | } | ||||
| @@ -113,13 +104,13 @@ namespace Discord.Commands | |||||
| for (int i = 0; i < parseResult.ParamValues.Count; i++) | for (int i = 0; i < parseResult.ParamValues.Count; i++) | ||||
| { | { | ||||
| if (!parseResult.ParamValues[i].IsSuccess) | if (!parseResult.ParamValues[i].IsSuccess) | ||||
| return Task.FromResult(ExecuteResult.FromError(parseResult.ParamValues[i])); | |||||
| return Task.FromResult(parseResult.ParamValues[i] as IResult); | |||||
| paramList[i] = parseResult.ParamValues[i].Values.First().Value; | paramList[i] = parseResult.ParamValues[i].Values.First().Value; | ||||
| } | } | ||||
| return ExecuteAsync(context, argList, paramList, map); | return ExecuteAsync(context, argList, paramList, map); | ||||
| } | } | ||||
| public async Task<ExecuteResult> ExecuteAsync(ICommandContext context, IEnumerable<object> argList, IEnumerable<object> paramList, IDependencyMap map) | |||||
| public async Task<IResult> ExecuteAsync(ICommandContext context, IEnumerable<object> argList, IEnumerable<object> paramList, IDependencyMap map) | |||||
| { | { | ||||
| if (map == null) | if (map == null) | ||||
| map = DependencyMap.Empty; | map = DependencyMap.Empty; | ||||
| @@ -134,7 +125,7 @@ namespace Discord.Commands | |||||
| var argument = args[position]; | var argument = args[position]; | ||||
| var result = await parameter.CheckPreconditionsAsync(context, argument, map).ConfigureAwait(false); | var result = await parameter.CheckPreconditionsAsync(context, argument, map).ConfigureAwait(false); | ||||
| if (!result.IsSuccess) | if (!result.IsSuccess) | ||||
| return ExecuteResult.FromError(result); | |||||
| return result; | |||||
| } | } | ||||
| switch (RunMode) | switch (RunMode) | ||||
| @@ -149,7 +140,7 @@ namespace Discord.Commands | |||||
| }); | }); | ||||
| break; | break; | ||||
| } | } | ||||
| return ExecuteResult.FromSuccess(); | |||||
| return ExecuteResult.Success; | |||||
| } | } | ||||
| catch (Exception ex) | catch (Exception ex) | ||||
| { | { | ||||
| @@ -51,7 +51,7 @@ namespace Discord.Commands | |||||
| return result; | return result; | ||||
| } | } | ||||
| return PreconditionResult.FromSuccess(); | |||||
| return PreconditionResult.Success; | |||||
| } | } | ||||
| public async Task<TypeReaderResult> Parse(ICommandContext context, string input) | public async Task<TypeReaderResult> Parse(ICommandContext context, string input) | ||||
| @@ -30,7 +30,7 @@ namespace Discord.Commands | |||||
| AddResult(results, channel as T, channel.Name == input ? 0.80f : 0.70f); | AddResult(results, channel as T, channel.Name == input ? 0.80f : 0.70f); | ||||
| if (results.Count > 0) | if (results.Count > 0) | ||||
| return TypeReaderResult.FromSuccess(results.Values); | |||||
| return TypeReaderResult.FromMultipleSuccess(results.Values.ToReadOnlyCollection()); | |||||
| } | } | ||||
| return TypeReaderResult.FromError(CommandError.ObjectNotFound, "Channel not found."); | return TypeReaderResult.FromError(CommandError.ObjectNotFound, "Channel not found."); | ||||
| @@ -31,7 +31,7 @@ namespace Discord.Commands | |||||
| AddResult(results, role as T, role.Name == input ? 0.80f : 0.70f); | AddResult(results, role as T, role.Name == input ? 0.80f : 0.70f); | ||||
| if (results.Count > 0) | if (results.Count > 0) | ||||
| return Task.FromResult(TypeReaderResult.FromSuccess(results.Values)); | |||||
| return Task.FromResult(TypeReaderResult.FromMultipleSuccess(results.Values.ToReadOnlyCollection())); | |||||
| } | } | ||||
| return Task.FromResult(TypeReaderResult.FromError(CommandError.ObjectNotFound, "Role not found.")); | return Task.FromResult(TypeReaderResult.FromError(CommandError.ObjectNotFound, "Role not found.")); | ||||
| } | } | ||||
| @@ -75,7 +75,7 @@ namespace Discord.Commands | |||||
| } | } | ||||
| if (results.Count > 0) | if (results.Count > 0) | ||||
| return TypeReaderResult.FromSuccess(results.Values.ToImmutableArray()); | |||||
| return TypeReaderResult.FromMultipleSuccess(results.Values.ToReadOnlyCollection()); | |||||
| return TypeReaderResult.FromError(CommandError.ObjectNotFound, "User not found."); | return TypeReaderResult.FromError(CommandError.ObjectNotFound, "User not found."); | ||||
| } | } | ||||
| @@ -6,6 +6,9 @@ namespace Discord.Commands | |||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public class ExecuteResult : IResult | public class ExecuteResult : IResult | ||||
| { | { | ||||
| private static readonly ExecuteResult _success = new ExecuteResult(null, null, null); | |||||
| public static ExecuteResult Success => _success; | |||||
| public Exception Exception { get; } | public Exception Exception { get; } | ||||
| public CommandError? Error { get; } | public CommandError? Error { get; } | ||||
| @@ -20,14 +23,10 @@ namespace Discord.Commands | |||||
| ErrorReason = errorReason; | ErrorReason = errorReason; | ||||
| } | } | ||||
| public static ExecuteResult FromSuccess() | |||||
| => new ExecuteResult(null, null, null); | |||||
| public static ExecuteResult FromError(CommandError error, string reason) | public static ExecuteResult FromError(CommandError error, string reason) | ||||
| => new ExecuteResult(null, error, reason); | => new ExecuteResult(null, error, reason); | ||||
| public static ExecuteResult FromError(Exception ex) | public static ExecuteResult FromError(Exception ex) | ||||
| => new ExecuteResult(ex, CommandError.Exception, ex.Message); | => new ExecuteResult(ex, CommandError.Exception, ex.Message); | ||||
| public static ExecuteResult FromError(IResult result) | |||||
| => new ExecuteResult(null, result.Error, result.ErrorReason); | |||||
| public override string ToString() => IsSuccess ? "Success" : $"{Error}: {ErrorReason}"; | public override string ToString() => IsSuccess ? "Success" : $"{Error}: {ErrorReason}"; | ||||
| private string DebuggerDisplay => IsSuccess ? "Success" : $"{Error}: {ErrorReason}"; | private string DebuggerDisplay => IsSuccess ? "Success" : $"{Error}: {ErrorReason}"; | ||||
| @@ -53,7 +53,8 @@ namespace Discord.Commands | |||||
| public static ParseResult FromError(CommandError error, string reason) | public static ParseResult FromError(CommandError error, string reason) | ||||
| => new ParseResult(null, null, error, reason); | => new ParseResult(null, null, error, reason); | ||||
| public static ParseResult FromError(IResult result) | |||||
| internal static ParseResult FromTypeReaderResult(TypeReaderResult result) | |||||
| => new ParseResult(null, null, result.Error, result.ErrorReason); | => new ParseResult(null, null, result.Error, result.ErrorReason); | ||||
| public override string ToString() => IsSuccess ? "Success" : $"{Error}: {ErrorReason}"; | public override string ToString() => IsSuccess ? "Success" : $"{Error}: {ErrorReason}"; | ||||
| @@ -5,6 +5,9 @@ namespace Discord.Commands | |||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public class PreconditionResult : IResult | public class PreconditionResult : IResult | ||||
| { | { | ||||
| private static readonly PreconditionResult _success = new PreconditionResult(null, null); | |||||
| public static PreconditionResult Success => _success; | |||||
| public CommandError? Error { get; } | public CommandError? Error { get; } | ||||
| public string ErrorReason { get; } | public string ErrorReason { get; } | ||||
| @@ -16,12 +19,8 @@ namespace Discord.Commands | |||||
| ErrorReason = errorReason; | ErrorReason = errorReason; | ||||
| } | } | ||||
| public static PreconditionResult FromSuccess() | |||||
| => new PreconditionResult(null, null); | |||||
| public static PreconditionResult FromError(string reason) | public static PreconditionResult FromError(string reason) | ||||
| => new PreconditionResult(CommandError.UnmetPrecondition, reason); | => new PreconditionResult(CommandError.UnmetPrecondition, reason); | ||||
| public static PreconditionResult FromError(IResult result) | |||||
| => new PreconditionResult(result.Error, result.ErrorReason); | |||||
| public override string ToString() => IsSuccess ? "Success" : $"{Error}: {ErrorReason}"; | public override string ToString() => IsSuccess ? "Success" : $"{Error}: {ErrorReason}"; | ||||
| private string DebuggerDisplay => IsSuccess ? "Success" : $"{Error}: {ErrorReason}"; | private string DebuggerDisplay => IsSuccess ? "Success" : $"{Error}: {ErrorReason}"; | ||||
| @@ -26,8 +26,6 @@ namespace Discord.Commands | |||||
| => new SearchResult(text, commands, null, null); | => new SearchResult(text, commands, null, null); | ||||
| public static SearchResult FromError(CommandError error, string reason) | public static SearchResult FromError(CommandError error, string reason) | ||||
| => new SearchResult(null, null, error, reason); | => new SearchResult(null, null, error, reason); | ||||
| public static SearchResult FromError(IResult result) | |||||
| => new SearchResult(null, null, result.Error, result.ErrorReason); | |||||
| public override string ToString() => IsSuccess ? "Success" : $"{Error}: {ErrorReason}"; | public override string ToString() => IsSuccess ? "Success" : $"{Error}: {ErrorReason}"; | ||||
| private string DebuggerDisplay => IsSuccess ? $"Success ({Commands.Count} Results)" : $"{Error}: {ErrorReason}"; | private string DebuggerDisplay => IsSuccess ? $"Success ({Commands.Count} Results)" : $"{Error}: {ErrorReason}"; | ||||
| @@ -6,7 +6,7 @@ using System.Diagnostics; | |||||
| namespace Discord.Commands | namespace Discord.Commands | ||||
| { | { | ||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public class TypeReaderValue | |||||
| public struct TypeReaderValue | |||||
| { | { | ||||
| public object Value { get; } | public object Value { get; } | ||||
| public float Score { get; } | public float Score { get; } | ||||
| @@ -40,14 +40,13 @@ namespace Discord.Commands | |||||
| public static TypeReaderResult FromSuccess(object value) | public static TypeReaderResult FromSuccess(object value) | ||||
| => new TypeReaderResult(ImmutableArray.Create(new TypeReaderValue(value, 1.0f)), null, null); | => new TypeReaderResult(ImmutableArray.Create(new TypeReaderValue(value, 1.0f)), null, null); | ||||
| public static TypeReaderResult FromSuccess(TypeReaderValue value) | |||||
| public static TypeReaderResult FromSingleSuccess(TypeReaderValue value) | |||||
| => new TypeReaderResult(ImmutableArray.Create(value), null, null); | => new TypeReaderResult(ImmutableArray.Create(value), null, null); | ||||
| public static TypeReaderResult FromSuccess(IReadOnlyCollection<TypeReaderValue> values) | |||||
| public static TypeReaderResult FromMultipleSuccess(IReadOnlyCollection<TypeReaderValue> values) | |||||
| => new TypeReaderResult(values, null, null); | => new TypeReaderResult(values, null, null); | ||||
| public static TypeReaderResult FromError(CommandError error, string reason) | public static TypeReaderResult FromError(CommandError error, string reason) | ||||
| => new TypeReaderResult(null, error, reason); | => new TypeReaderResult(null, error, reason); | ||||
| public static TypeReaderResult FromError(IResult result) | |||||
| => new TypeReaderResult(null, result.Error, result.ErrorReason); | |||||
| public override string ToString() => IsSuccess ? "Success" : $"{Error}: {ErrorReason}"; | public override string ToString() => IsSuccess ? "Success" : $"{Error}: {ErrorReason}"; | ||||
| private string DebuggerDisplay => IsSuccess ? $"Success ({string.Join(", ", Values)})" : $"{Error}: {ErrorReason}"; | private string DebuggerDisplay => IsSuccess ? $"Success ({string.Join(", ", Values)})" : $"{Error}: {ErrorReason}"; | ||||