✨ Fix parsing of flag arguments that start with '-', i.e. a negative integer, add captions for flag argument
This commit is contained in:
parent
2fbd90dfee
commit
5f466fcbc0
4 changed files with 151 additions and 12 deletions
|
|
@ -27,7 +27,11 @@ import cloud.commandframework.arguments.CommandArgument;
|
||||||
import cloud.commandframework.arguments.flags.CommandFlag;
|
import cloud.commandframework.arguments.flags.CommandFlag;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||||
|
import cloud.commandframework.captions.Caption;
|
||||||
|
import cloud.commandframework.captions.CaptionVariable;
|
||||||
|
import cloud.commandframework.captions.StandardCaptionKeys;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
|
import cloud.commandframework.exceptions.parsing.ParserException;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
@ -106,11 +110,7 @@ public final class FlagArgument<C> extends CommandArgument<C, Object> {
|
||||||
CommandFlag<?> currentFlag = null;
|
CommandFlag<?> currentFlag = null;
|
||||||
|
|
||||||
for (final @NonNull String string : inputQueue) {
|
for (final @NonNull String string : inputQueue) {
|
||||||
if (string.startsWith("-")) {
|
if (string.startsWith("-") && currentFlag == null) {
|
||||||
if (currentFlag != null && currentFlag.getCommandArgument() != null) {
|
|
||||||
return ArgumentParseResult.failure(
|
|
||||||
new IllegalArgumentException(String.format("Missing argument for '%s'", currentFlag.getName())));
|
|
||||||
}
|
|
||||||
if (string.startsWith("--")) {
|
if (string.startsWith("--")) {
|
||||||
final String flagName = string.substring(2);
|
final String flagName = string.substring(2);
|
||||||
for (final CommandFlag<?> flag : this.flags) {
|
for (final CommandFlag<?> flag : this.flags) {
|
||||||
|
|
@ -131,11 +131,17 @@ public final class FlagArgument<C> extends CommandArgument<C, Object> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (currentFlag == null) {
|
if (currentFlag == null) {
|
||||||
return ArgumentParseResult.failure(
|
return ArgumentParseResult.failure(new FlagParseException(
|
||||||
new IllegalArgumentException(String.format("Unknown flag '%s'", string)));
|
string,
|
||||||
|
FailureReason.UNKNOWN_FLAG,
|
||||||
|
commandContext
|
||||||
|
));
|
||||||
} else if (parsedFlags.contains(currentFlag)) {
|
} else if (parsedFlags.contains(currentFlag)) {
|
||||||
return ArgumentParseResult.failure(
|
return ArgumentParseResult.failure(new FlagParseException(
|
||||||
new IllegalArgumentException(String.format("Duplicate flag '%s'", string)));
|
string,
|
||||||
|
FailureReason.DUPLICATE_FLAG,
|
||||||
|
commandContext
|
||||||
|
));
|
||||||
}
|
}
|
||||||
parsedFlags.add(currentFlag);
|
parsedFlags.add(currentFlag);
|
||||||
if (currentFlag.getCommandArgument() == null) {
|
if (currentFlag.getCommandArgument() == null) {
|
||||||
|
|
@ -146,9 +152,11 @@ public final class FlagArgument<C> extends CommandArgument<C, Object> {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (currentFlag == null) {
|
if (currentFlag == null) {
|
||||||
return ArgumentParseResult.failure(
|
return ArgumentParseResult.failure(new FlagParseException(
|
||||||
new IllegalArgumentException(String.format("No flag started. Don't"
|
string,
|
||||||
+ " know what to do with '%s'", string)));
|
FailureReason.NO_FLAG_STARTED,
|
||||||
|
commandContext
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
final ArgumentParseResult<?> result =
|
final ArgumentParseResult<?> result =
|
||||||
((CommandArgument) currentFlag.getCommandArgument())
|
((CommandArgument) currentFlag.getCommandArgument())
|
||||||
|
|
@ -168,6 +176,13 @@ public final class FlagArgument<C> extends CommandArgument<C, Object> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (currentFlag != null) {
|
||||||
|
return ArgumentParseResult.failure(new FlagParseException(
|
||||||
|
currentFlag.getName(),
|
||||||
|
FailureReason.MISSING_ARGUMENT,
|
||||||
|
commandContext
|
||||||
|
));
|
||||||
|
}
|
||||||
/* We've consumed everything */
|
/* We've consumed everything */
|
||||||
inputQueue.clear();
|
inputQueue.clear();
|
||||||
return ArgumentParseResult.success(FLAG_PARSE_RESULT_OBJECT);
|
return ArgumentParseResult.success(FLAG_PARSE_RESULT_OBJECT);
|
||||||
|
|
@ -223,4 +238,71 @@ public final class FlagArgument<C> extends CommandArgument<C, Object> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag parse exception
|
||||||
|
*/
|
||||||
|
public static final class FlagParseException extends ParserException {
|
||||||
|
|
||||||
|
private final String input;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new flag parse exception
|
||||||
|
*
|
||||||
|
* @param input Input
|
||||||
|
* @param failureReason The reason of failure
|
||||||
|
* @param context Command context
|
||||||
|
*/
|
||||||
|
public FlagParseException(
|
||||||
|
final @NonNull String input,
|
||||||
|
final @NonNull FailureReason failureReason,
|
||||||
|
final @NonNull CommandContext<?> context
|
||||||
|
) {
|
||||||
|
super(
|
||||||
|
FlagArgument.FlagArgumentParser.class,
|
||||||
|
context,
|
||||||
|
failureReason.getCaption(),
|
||||||
|
CaptionVariable.of("input", input),
|
||||||
|
CaptionVariable.of("flag", input)
|
||||||
|
);
|
||||||
|
this.input = input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the supplied input
|
||||||
|
*
|
||||||
|
* @return String value
|
||||||
|
*/
|
||||||
|
public String getInput() {
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reasons for which flag parsing may fail
|
||||||
|
*/
|
||||||
|
public enum FailureReason {
|
||||||
|
|
||||||
|
UNKNOWN_FLAG(StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_FLAG_UNKNOWN_FLAG),
|
||||||
|
DUPLICATE_FLAG(StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_FLAG_DUPLICATE_FLAG),
|
||||||
|
NO_FLAG_STARTED(StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_FLAG_NO_FLAG_STARTED),
|
||||||
|
MISSING_ARGUMENT(StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_FLAG_MISSING_ARGUMENT);
|
||||||
|
|
||||||
|
private final Caption caption;
|
||||||
|
|
||||||
|
FailureReason(final @NonNull Caption caption) {
|
||||||
|
this.caption = caption;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the caption used for this failure reason
|
||||||
|
*
|
||||||
|
* @return The caption
|
||||||
|
*/
|
||||||
|
public @NonNull Caption getCaption() {
|
||||||
|
return this.caption;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,22 @@ public class SimpleCaptionRegistry<C> implements FactoryDelegatingCaptionRegistr
|
||||||
* Default caption for {@link StandardCaptionKeys#ARGUMENT_PARSE_FAILURE_UUID}
|
* Default caption for {@link StandardCaptionKeys#ARGUMENT_PARSE_FAILURE_UUID}
|
||||||
*/
|
*/
|
||||||
public static final String ARGUMENT_PARSE_FAILURE_UUID = "'{input}' is not a valid UUID";
|
public static final String ARGUMENT_PARSE_FAILURE_UUID = "'{input}' is not a valid UUID";
|
||||||
|
/**
|
||||||
|
* Default caption for {@link StandardCaptionKeys#ARGUMENT_PARSE_FAILURE_FLAG_UNKNOWN_FLAG}
|
||||||
|
*/
|
||||||
|
public static final String ARGUMENT_PARSE_FAILURE_FLAG_UNKNOWN_FLAG = "Unknown flag '{flag}'";
|
||||||
|
/**
|
||||||
|
* Default caption for {@link StandardCaptionKeys#ARGUMENT_PARSE_FAILURE_FLAG_DUPLICATE_FLAG}
|
||||||
|
*/
|
||||||
|
public static final String ARGUMENT_PARSE_FAILURE_FLAG_DUPLICATE_FLAG = "Duplicate flag '{flag}'";
|
||||||
|
/**
|
||||||
|
* Default caption for {@link StandardCaptionKeys#ARGUMENT_PARSE_FAILURE_FLAG_NO_FLAG_STARTED}
|
||||||
|
*/
|
||||||
|
public static final String ARGUMENT_PARSE_FAILURE_FLAG_NO_FLAG_STARTED = "No flag started. Don't know what to do with '{input}'";
|
||||||
|
/**
|
||||||
|
* Default caption for {@link StandardCaptionKeys#ARGUMENT_PARSE_FAILURE_FLAG_MISSING_ARGUMENT}
|
||||||
|
*/
|
||||||
|
public static final String ARGUMENT_PARSE_FAILURE_FLAG_MISSING_ARGUMENT = "Missing argument for '{flag}'";
|
||||||
|
|
||||||
private final Map<Caption, BiFunction<Caption, C, String>> messageFactories = new HashMap<>();
|
private final Map<Caption, BiFunction<Caption, C, String>> messageFactories = new HashMap<>();
|
||||||
|
|
||||||
|
|
@ -88,6 +104,22 @@ public class SimpleCaptionRegistry<C> implements FactoryDelegatingCaptionRegistr
|
||||||
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_UUID,
|
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_UUID,
|
||||||
(caption, sender) -> ARGUMENT_PARSE_FAILURE_UUID
|
(caption, sender) -> ARGUMENT_PARSE_FAILURE_UUID
|
||||||
);
|
);
|
||||||
|
this.registerMessageFactory(
|
||||||
|
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_FLAG_UNKNOWN_FLAG,
|
||||||
|
(caption, sender) -> ARGUMENT_PARSE_FAILURE_FLAG_UNKNOWN_FLAG
|
||||||
|
);
|
||||||
|
this.registerMessageFactory(
|
||||||
|
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_FLAG_DUPLICATE_FLAG,
|
||||||
|
(caption, sender) -> ARGUMENT_PARSE_FAILURE_FLAG_DUPLICATE_FLAG
|
||||||
|
);
|
||||||
|
this.registerMessageFactory(
|
||||||
|
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_FLAG_NO_FLAG_STARTED,
|
||||||
|
(caption, sender) -> ARGUMENT_PARSE_FAILURE_FLAG_NO_FLAG_STARTED
|
||||||
|
);
|
||||||
|
this.registerMessageFactory(
|
||||||
|
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_FLAG_MISSING_ARGUMENT,
|
||||||
|
(caption, sender) -> ARGUMENT_PARSE_FAILURE_FLAG_MISSING_ARGUMENT
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,22 @@ public final class StandardCaptionKeys {
|
||||||
* Variables: {input}, {pattern}
|
* Variables: {input}, {pattern}
|
||||||
*/
|
*/
|
||||||
public static final Caption ARGUMENT_PARSE_FAILURE_REGEX = of("argument.parse.failure.regex");
|
public static final Caption ARGUMENT_PARSE_FAILURE_REGEX = of("argument.parse.failure.regex");
|
||||||
|
/**
|
||||||
|
* Variables: {flag}
|
||||||
|
*/
|
||||||
|
public static final Caption ARGUMENT_PARSE_FAILURE_FLAG_UNKNOWN_FLAG = of("argument.parse.failure.flag.unknown");
|
||||||
|
/**
|
||||||
|
* Variables: {flag}
|
||||||
|
*/
|
||||||
|
public static final Caption ARGUMENT_PARSE_FAILURE_FLAG_DUPLICATE_FLAG = of("argument.parse.failure.flag.duplicate_flag");
|
||||||
|
/**
|
||||||
|
* Variables: {input}
|
||||||
|
*/
|
||||||
|
public static final Caption ARGUMENT_PARSE_FAILURE_FLAG_NO_FLAG_STARTED = of("argument.parse.failure.flag.no_flag_started");
|
||||||
|
/**
|
||||||
|
* Variables: {flag}
|
||||||
|
*/
|
||||||
|
public static final Caption ARGUMENT_PARSE_FAILURE_FLAG_MISSING_ARGUMENT = of("argument.parse.failure.flag.missing_argument");
|
||||||
|
|
||||||
private StandardCaptionKeys() {
|
private StandardCaptionKeys() {
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -182,6 +182,15 @@ public final class MinecraftHelp<C> {
|
||||||
this.colors = colors;
|
this.colors = colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the colors used for help messages.
|
||||||
|
*
|
||||||
|
* @return The active {@link HelpColors}
|
||||||
|
*/
|
||||||
|
public @NonNull HelpColors getHelpColors() {
|
||||||
|
return this.colors;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the length of the header/footer of help menus
|
* Set the length of the header/footer of help menus
|
||||||
* <p>
|
* <p>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue