Skip to content

Commit

Permalink
GH-212 Add InvalidUsage to represent invalid command usage, instead B…
Browse files Browse the repository at this point in the history
…lank. (#212)

* Add InvalidUsage to represent invalid command usage, instead Blank.

* Remove default "text" string argument suggestion.

* Fix compile conflicts in bukkit module.
  • Loading branch information
Rollczi authored May 10, 2023
1 parent 0eaab65 commit 4369020
Show file tree
Hide file tree
Showing 22 changed files with 141 additions and 79 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.rollczi.litecommands.bukkit;

import dev.rollczi.litecommands.command.LiteInvocation;
import dev.rollczi.litecommands.command.execute.ExecuteResult;
import dev.rollczi.litecommands.command.section.CommandSection;
import dev.rollczi.litecommands.handle.ExecuteResultHandler;
import dev.rollczi.litecommands.platform.ExecuteListener;
Expand Down Expand Up @@ -65,7 +66,7 @@ private SimpleCommand createCommand(CommandSection<CommandSender> command, Execu
LiteInvocation invocation = new LiteInvocation(new BukkitSender(sender), command.getName(), command.getName());

try {
this.executeResultHandler.handleResult(sender, invocation, requiredPermissions);
this.executeResultHandler.handleResult(sender, invocation, ExecuteResult.invalid(null, requiredPermissions), requiredPermissions);
return true;
} catch (IllegalStateException exception) {
return false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package dev.rollczi.litecommands.argument.basictype;

import dev.rollczi.litecommands.argument.simple.OneArgument;
import dev.rollczi.litecommands.command.InvalidUsage;
import dev.rollczi.litecommands.command.LiteInvocation;
import dev.rollczi.litecommands.suggestion.Suggestion;
import panda.std.Blank;
import panda.std.Result;

import java.util.List;
Expand All @@ -21,7 +21,7 @@ protected AbstractBasicTypeArgument(Function<String, T> parser, Supplier<String[
}

@Override
public Result<T, Blank> parse(LiteInvocation invocation, String argument) {
public Result<T, InvalidUsage> parse(LiteInvocation invocation, String argument) {
return TypeUtils.parse(() -> this.parser.apply(argument));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package dev.rollczi.litecommands.argument.basictype;

import dev.rollczi.litecommands.command.InvalidUsage;
import dev.rollczi.litecommands.command.LiteInvocation;
import dev.rollczi.litecommands.suggestion.Suggestion;
import panda.std.Blank;
import panda.std.Result;

import java.util.ArrayList;
Expand All @@ -13,20 +13,20 @@

final class TypeUtils {

static final String[] NUMBER_SHORT_SUGGESTION = { "0", "1", "5", "10", "50" };
static final String[] NUMBER_SUGGESTION = { "0", "1", "5", "10", "50", "100", "500" };
static final String[] NUMBER_SHORT_SUGGESTION = { "0", "1", "5", "10", "25", "50" };
static final String[] NUMBER_SUGGESTION = { "0", "1", "5", "10", "25", "50", "100", "250", "500" };
static final String[] DECIMAL_SUGGESTION = { "0", "1", "1.5", "10", "10.5", "100", "100.5" };

static final String[] STRING_SUGGESTION = { "text" };
static final String[] STRING_SUGGESTION = {};
static final String[] CHARACTER_SUGGESTION = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "r", "s", "t", "u", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };

static final String[] BOOLEAN_SUGGESTION = { "true", "false" };

private TypeUtils() {
}

static <T> Result<T, Blank> parse(Supplier<T> parse) {
return Result.supplyThrowing(NumberFormatException.class, parse::get).mapErrToBlank();
static <T> Result<T, InvalidUsage> parse(Supplier<T> parse) {
return Result.supplyThrowing(NumberFormatException.class, parse::get).mapErr(error -> InvalidUsage.INSTANCE);
}

static List<Suggestion> suggestion(Function<String, ?> parse, LiteInvocation invocation, String... suggestions) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.rollczi.litecommands.argument.basictype.time;

import dev.rollczi.litecommands.argument.simple.MultilevelArgument;
import dev.rollczi.litecommands.command.InvalidUsage;
import dev.rollczi.litecommands.command.LiteInvocation;
import dev.rollczi.litecommands.suggestion.Suggestion;
import panda.std.Result;
Expand Down Expand Up @@ -40,9 +41,9 @@ protected TemporalAccessorArgument(String formatterPattern, TemporalQuery<T> que
}

@Override
public Result<T, ?> parseMultilevel(LiteInvocation invocation, String... arguments) {
public Result<T, InvalidUsage> parseMultilevel(LiteInvocation invocation, String... arguments) {
return this.parseTemporal(String.join(MULTI_LEVEL_ARGUMENT_SEPARATOR, arguments))
.mapErrToBlank();
.mapErr(error -> InvalidUsage.INSTANCE);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.rollczi.litecommands.argument.basictype.time;

import dev.rollczi.litecommands.argument.simple.MultilevelArgument;
import dev.rollczi.litecommands.command.InvalidUsage;
import dev.rollczi.litecommands.command.LiteInvocation;
import dev.rollczi.litecommands.shared.EstimatedTemporalAmountParser;
import dev.rollczi.litecommands.suggestion.Suggestion;
Expand All @@ -26,7 +27,7 @@ protected TemporalAmountArgument(EstimatedTemporalAmountParser<T> parser, Suppli
@Override
public Result<T, ?> parseMultilevel(LiteInvocation invocation, String... arguments) {
return this.parseTemporal(String.join(MULTI_LEVEL_ARGUMENT_SEPARATOR, arguments))
.mapErrToBlank();
.mapErr(error -> InvalidUsage.INSTANCE);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package dev.rollczi.litecommands.argument.basictype.time;

import dev.rollczi.litecommands.argument.simple.OneArgument;
import dev.rollczi.litecommands.command.InvalidUsage;
import dev.rollczi.litecommands.command.LiteInvocation;
import dev.rollczi.litecommands.suggestion.Suggestion;
import panda.std.Blank;
import panda.std.Result;

import java.time.ZoneId;
Expand All @@ -12,9 +12,9 @@
public class ZoneIdArgument implements OneArgument<ZoneId> {

@Override
public Result<ZoneId, Blank> parse(LiteInvocation invocation, String argument) {
public Result<ZoneId, InvalidUsage> parse(LiteInvocation invocation, String argument) {
return Result.supplyThrowing(() -> ZoneId.of(argument))
.mapErrToBlank();
.mapErr(exception -> InvalidUsage.INSTANCE);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import dev.rollczi.litecommands.argument.ArgumentContext;
import dev.rollczi.litecommands.argument.ParameterHandler;
import dev.rollczi.litecommands.argument.simple.MultilevelArgument;
import dev.rollczi.litecommands.command.InvalidUsage;
import dev.rollczi.litecommands.command.LiteInvocation;
import dev.rollczi.litecommands.command.MatchResult;
import dev.rollczi.litecommands.suggestion.Suggestion;
import panda.std.Blank;
import panda.std.Option;
import panda.std.Result;

Expand Down Expand Up @@ -47,7 +47,7 @@ public MatchResult match(LiteInvocation invocation, ArgumentContext<Opt> context
if (parsed.isErr()) {
Object error = parsed.getError();

if (error instanceof Blank && !context.annotation().strict()) {
if (error instanceof InvalidUsage && !context.annotation().strict()) {
return MatchResult.notMatched();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import dev.rollczi.litecommands.command.LiteInvocation;
import dev.rollczi.litecommands.command.MatchResult;
import dev.rollczi.litecommands.suggestion.Suggestion;
import panda.std.Blank;
import panda.std.Result;

import java.lang.reflect.Parameter;
Expand Down Expand Up @@ -34,13 +33,7 @@ public MatchResult match(LiteInvocation invocation, ArgumentContext<Arg> context
Result<T, ?> parsed = this.multilevel.parseMultilevel(invocation, argumentsToParse.toArray(new String[0]));

if (parsed.isErr()) {
Object error = parsed.getError();

if (error instanceof Blank) {
return MatchResult.notMatched();
}

return MatchResult.notMatched(error);
return MatchResult.notMatched(parsed.getError());
}

return MatchResult.matched(parsed.get(), multilevel.countMultilevel());
Expand All @@ -51,11 +44,6 @@ public List<Suggestion> suggestion(LiteInvocation invocation, Parameter paramete
return this.multilevel.suggest(invocation);
}

@Override
public boolean isOptional() {
return false;
}

@Override
public Class<?> getNativeClass() {
return this.multilevel.getClass();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package dev.rollczi.litecommands.command;

public final class InvalidUsage {

public static final InvalidUsage INSTANCE = new InvalidUsage();

public InvalidUsage() {
}

@Override
public int hashCode() {
return 0;
}

@Override
public boolean equals(Object obj) {
return obj instanceof InvalidUsage;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class ExecuteResult {
private final boolean invalid;
private final Object result;

public ExecuteResult(FindResult based, boolean success, boolean invalid, Object result) {
private ExecuteResult(FindResult based, boolean success, boolean invalid, Object result) {
this.based = based;
this.success = success;
this.invalid = invalid;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package dev.rollczi.litecommands.handle;

import dev.rollczi.litecommands.command.InvalidUsage;
import dev.rollczi.litecommands.command.LiteInvocation;
import dev.rollczi.litecommands.command.execute.ExecuteResult;
import dev.rollczi.litecommands.schematic.Schematic;
import dev.rollczi.litecommands.schematic.SchematicFormat;
import dev.rollczi.litecommands.schematic.SchematicGenerator;
import dev.rollczi.litecommands.shared.MapUtil;
import org.jetbrains.annotations.ApiStatus;
import panda.std.Blank;
import panda.std.Option;

import java.util.HashMap;
Expand Down Expand Up @@ -37,38 +38,49 @@ public SchematicFormat getSchematicFormat() {
return this.schematicFormat;
}

public void handle(SENDER sender, LiteInvocation invocation, ExecuteResult result) {
Object object = result.getResult();
public void handle(SENDER sender, LiteInvocation invocation, ExecuteResult executeResult) {
this.handle(sender, invocation, executeResult, executeResult.getResult());
}

private void handle(SENDER sender, LiteInvocation invocation, ExecuteResult executeResult, Object object) {
if (object == null) {
if (!result.isFailure()) {
if (!executeResult.isFailure()) {
return;
}

object = this.schematicGenerator.generateSchematic(result.getBased(), this.schematicFormat);
Schematic schematic = this.schematicGenerator.generateSchematic(executeResult.getBased(), this.schematicFormat);

this.handle(sender, invocation, executeResult, schematic);
return;
}

if (object instanceof InvalidUsage) {
Schematic schematic = this.schematicGenerator.generateSchematic(executeResult.getBased(), this.schematicFormat);

this.handle(sender, invocation, executeResult, schematic);
return;
}

if (object instanceof CompletableFuture<?>) {
CompletableFuture<?> future = ((CompletableFuture<?>) object);

future.whenComplete((obj, ex) -> {
if (ex != null) {
ex.printStackTrace();
future.whenComplete((obj, throwable) -> {
if (throwable != null) {
throwable.printStackTrace();
return;
}

this.handleResult(sender, invocation, obj);
this.handle(sender, invocation, executeResult, obj);
});

return;
}


this.handleResult(sender, invocation, object);
this.handleResult(sender, invocation, executeResult, object);
}

@ApiStatus.Internal
public void handleResult(SENDER sender, LiteInvocation invocation, Object object) {
public void handleResult(SENDER sender, LiteInvocation invocation, ExecuteResult executeResult, Object object) {
Class<?> type = object.getClass();
Option<Handler<SENDER, ?>> handlerOpt = MapUtil.findSuperTypeOf(type, this.handlers);

Expand All @@ -84,18 +96,11 @@ public void handleResult(SENDER sender, LiteInvocation invocation, Object object
throw new RuntimeException("Exception thrown during command execution", (Throwable) object);
}

if (object instanceof Blank) {
return;
}

throw new IllegalStateException("Missing result handler for type " + type);
}

Object to = this.handleRedirector(forwarding, object);
Handler<SENDER, ?> handler = MapUtil.findSuperTypeOf(to.getClass(), this.handlers)
.orThrow(() -> new IllegalStateException("Missing result handler for type " + type + " or for redirected type " + to.getClass()));

this.handleHandler(handler, sender, invocation, to);
this.handle(sender, invocation, executeResult, to);
return;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package dev.rollczi.litecommands.handle;

import dev.rollczi.litecommands.command.InvalidUsage;

public class LiteException extends RuntimeException {

private final Object result;
Expand All @@ -12,4 +14,8 @@ public Object getResult() {
return result;
}

public static LiteException newInvalidUsage() {
return new LiteException(InvalidUsage.INSTANCE);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import dev.rollczi.litecommands.command.execute.ExecuteResult;
import dev.rollczi.litecommands.handle.LiteException;
import dev.rollczi.litecommands.meta.CommandMeta;
import panda.std.Blank;
import panda.std.Option;

import java.lang.annotation.Annotation;
Expand All @@ -23,7 +22,7 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class LiteArgumentArgumentExecutor<SENDER> implements ArgumentExecutor<SENDER> {
class LiteArgumentExecutor<SENDER> implements ArgumentExecutor<SENDER> {

private final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

Expand All @@ -32,7 +31,7 @@ class LiteArgumentArgumentExecutor<SENDER> implements ArgumentExecutor<SENDER> {

private final CommandMeta meta = CommandMeta.create();

private LiteArgumentArgumentExecutor(List<AnnotatedParameterImpl<SENDER, ?>> arguments, MethodExecutor<SENDER> executor) {
private LiteArgumentExecutor(List<AnnotatedParameterImpl<SENDER, ?>> arguments, MethodExecutor<SENDER> executor) {
this.executor = executor;
this.arguments.addAll(arguments);
}
Expand Down Expand Up @@ -85,7 +84,7 @@ public FindResult<SENDER> find(LiteInvocation invocation, int route, FindResult<
continue;
}

if (resultNoMatchedResult.isPresent() && (!(resultNoMatchedResult.get() instanceof Blank))) {
if (resultNoMatchedResult.isPresent()) {
return currentResult
.withArgument(state)
.invalid(resultNoMatchedResult.get());
Expand Down Expand Up @@ -127,8 +126,8 @@ public CommandMeta meta() {
return this.meta;
}

static <T> LiteArgumentArgumentExecutor<T> of(List<AnnotatedParameterImpl<T, ?>> arguments, MethodExecutor<T> executor) {
return new LiteArgumentArgumentExecutor<>(arguments, executor);
static <T> LiteArgumentExecutor<T> of(List<AnnotatedParameterImpl<T, ?>> arguments, MethodExecutor<T> executor) {
return new LiteArgumentExecutor<>(arguments, executor);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ private ArgumentExecutor<SENDER> createExecutor(Object object, Method method, Co
}
}

LiteArgumentArgumentExecutor<SENDER> executor = LiteArgumentArgumentExecutor.of(arguments, methodExecutor);
LiteArgumentExecutor<SENDER> executor = LiteArgumentExecutor.of(arguments, methodExecutor);

executor.meta().applyCommandMeta(state.getMeta());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Integer executeClass(@Arg Integer argument) {
@Test
void testExecuteOnPlatform() {
this.testPlatform.execute("command", "int", "1.5")
.assertNullResult();
.assertInvalidUsage();

this.testPlatform.execute("command", "int", "5")
.assertResult(5);
Expand Down
Loading

0 comments on commit 4369020

Please sign in to comment.