diff --git a/src/Discord.Net.Commands/CommandParser.cs b/src/Discord.Net.Commands/CommandParser.cs index c77b56042..88698cda5 100644 --- a/src/Discord.Net.Commands/CommandParser.cs +++ b/src/Discord.Net.Commands/CommandParser.cs @@ -103,7 +103,7 @@ namespace Discord.Commands argBuilder.Append(c); continue; } - + if (IsOpenQuote(aliasMap, c)) { curPart = ParserPart.QuotedParameter; @@ -136,7 +136,7 @@ namespace Discord.Commands else argBuilder.Append(c); } - + if (argString != null) { if (curParam == null) @@ -149,7 +149,7 @@ namespace Discord.Commands var typeReaderResult = await curParam.ParseAsync(context, argString, services).ConfigureAwait(false); if (!typeReaderResult.IsSuccess && typeReaderResult.Error != CommandError.MultipleMatches) - return ParseResult.FromError(typeReaderResult); + return ParseResult.FromError(typeReaderResult, curParam); if (curParam.IsMultiple) { @@ -172,7 +172,7 @@ namespace Discord.Commands { var typeReaderResult = await curParam.ParseAsync(context, argBuilder.ToString(), services).ConfigureAwait(false); if (!typeReaderResult.IsSuccess) - return ParseResult.FromError(typeReaderResult); + return ParseResult.FromError(typeReaderResult, curParam); argList.Add(typeReaderResult); } @@ -180,7 +180,7 @@ namespace Discord.Commands return ParseResult.FromError(CommandError.ParseFailed, "Input text may not end on an incomplete escape."); if (curPart == ParserPart.QuotedParameter) return ParseResult.FromError(CommandError.ParseFailed, "A quoted parameter is incomplete."); - + //Add missing optionals for (int i = argList.Count; i < command.Parameters.Count; i++) { @@ -191,7 +191,7 @@ namespace Discord.Commands return ParseResult.FromError(CommandError.BadArgCount, "The input text has too few parameters."); argList.Add(TypeReaderResult.FromSuccess(param.DefaultValue)); } - + return ParseResult.FromSuccess(argList.ToImmutable(), paramList.ToImmutable()); } } diff --git a/src/Discord.Net.Commands/Results/ParseResult.cs b/src/Discord.Net.Commands/Results/ParseResult.cs index 8e10dc66c..43351b6bf 100644 --- a/src/Discord.Net.Commands/Results/ParseResult.cs +++ b/src/Discord.Net.Commands/Results/ParseResult.cs @@ -18,30 +18,40 @@ namespace Discord.Commands /// public string ErrorReason { get; } + /// + /// Provides information about the parameter that caused the parsing error. + /// + /// + /// A indicating the parameter info of the error that may have occurred during parsing; + /// null if the parsing was successful or the parsing error is not specific to a single parameter. + /// + public ParameterInfo ErrorParameter { get; } + /// public bool IsSuccess => !Error.HasValue; - private ParseResult(IReadOnlyList argValues, IReadOnlyList paramValues, CommandError? error, string errorReason) + private ParseResult(IReadOnlyList argValues, IReadOnlyList paramValues, CommandError? error, string errorReason, ParameterInfo errorParamInfo) { ArgValues = argValues; ParamValues = paramValues; Error = error; ErrorReason = errorReason; + ErrorParameter = errorParamInfo; } - + public static ParseResult FromSuccess(IReadOnlyList argValues, IReadOnlyList paramValues) { for (int i = 0; i < argValues.Count; i++) { if (argValues[i].Values.Count > 1) - return new ParseResult(argValues, paramValues, CommandError.MultipleMatches, "Multiple matches found."); + return new ParseResult(argValues, paramValues, CommandError.MultipleMatches, "Multiple matches found.", null); } for (int i = 0; i < paramValues.Count; i++) { if (paramValues[i].Values.Count > 1) - return new ParseResult(argValues, paramValues, CommandError.MultipleMatches, "Multiple matches found."); + return new ParseResult(argValues, paramValues, CommandError.MultipleMatches, "Multiple matches found.", null); } - return new ParseResult(argValues, paramValues, null, null); + return new ParseResult(argValues, paramValues, null, null, null); } public static ParseResult FromSuccess(IReadOnlyList argValues, IReadOnlyList paramValues) { @@ -55,15 +65,19 @@ namespace Discord.Commands for (int i = 0; i < paramValues.Count; i++) paramList[i] = TypeReaderResult.FromSuccess(paramValues[i]); } - return new ParseResult(argList, paramList, null, null); + return new ParseResult(argList, paramList, null, null, null); } public static ParseResult FromError(CommandError error, string reason) - => new ParseResult(null, null, error, reason); + => new ParseResult(null, null, error, reason, null); + public static ParseResult FromError(CommandError error, string reason, ParameterInfo parameterInfo) + => new ParseResult(null, null, error, reason, parameterInfo); public static ParseResult FromError(Exception ex) => FromError(CommandError.Exception, ex.Message); public static ParseResult FromError(IResult result) - => new ParseResult(null, null, result.Error, result.ErrorReason); + => new ParseResult(null, null, result.Error, result.ErrorReason, null); + public static ParseResult FromError(IResult result, ParameterInfo parameterInfo) + => new ParseResult(null, null, result.Error, result.ErrorReason, parameterInfo); public override string ToString() => IsSuccess ? "Success" : $"{Error}: {ErrorReason}"; private string DebuggerDisplay => IsSuccess ? $"Success ({ArgValues.Count}{(ParamValues.Count > 0 ? $" +{ParamValues.Count} Values" : "")})" : $"{Error}: {ErrorReason}";