✨ Allow default suggestion providers in @Parser
This commit is contained in:
parent
e5a35afb8a
commit
6cc3a21619
4 changed files with 55 additions and 7 deletions
|
|
@ -58,6 +58,7 @@ import java.lang.reflect.Parameter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -317,7 +318,20 @@ public final class AnnotationParser<C> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
final BiFunction<CommandContext<C>, String, List<String>> suggestionsProvider;
|
||||||
|
if (parser.suggestions().isEmpty()) {
|
||||||
|
suggestionsProvider = (context, input) -> Collections.emptyList();
|
||||||
|
} else {
|
||||||
|
suggestionsProvider = this.manager.getParserRegistry().getSuggestionProvider(parser.suggestions())
|
||||||
|
.orElseThrow(() -> new NullPointerException(
|
||||||
|
String.format(
|
||||||
|
"Cannot find the suggestions provider with name '%s'",
|
||||||
|
parser.suggestions()
|
||||||
|
)
|
||||||
|
));
|
||||||
|
}
|
||||||
final MethodArgumentParser<C, ?> methodArgumentParser = new MethodArgumentParser<>(
|
final MethodArgumentParser<C, ?> methodArgumentParser = new MethodArgumentParser<>(
|
||||||
|
suggestionsProvider,
|
||||||
instance,
|
instance,
|
||||||
method
|
method
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,9 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a method annotated with {@link Parser}
|
* Represents a method annotated with {@link Parser}
|
||||||
|
|
@ -42,19 +44,23 @@ import java.util.Queue;
|
||||||
*/
|
*/
|
||||||
public class MethodArgumentParser<C, T> implements ArgumentParser<C, T> {
|
public class MethodArgumentParser<C, T> implements ArgumentParser<C, T> {
|
||||||
|
|
||||||
|
private final BiFunction<CommandContext<C>, String, List<String>> suggestionProvider;
|
||||||
private final MethodHandle methodHandle;
|
private final MethodHandle methodHandle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new parser
|
* Create a new parser
|
||||||
*
|
*
|
||||||
|
* @param suggestionProvider Suggestion provider
|
||||||
* @param instance Instance that owns the method
|
* @param instance Instance that owns the method
|
||||||
* @param method The annotated method
|
* @param method The annotated method
|
||||||
* @throws Exception If the method lookup fails
|
* @throws Exception If the method lookup fails
|
||||||
*/
|
*/
|
||||||
public MethodArgumentParser(
|
public MethodArgumentParser(
|
||||||
|
final @NonNull BiFunction<CommandContext<C>, String, List<String>> suggestionProvider,
|
||||||
final @NonNull Object instance,
|
final @NonNull Object instance,
|
||||||
final @NonNull Method method
|
final @NonNull Method method
|
||||||
) throws Exception {
|
) throws Exception {
|
||||||
|
this.suggestionProvider = suggestionProvider;
|
||||||
this.methodHandle = MethodHandles.lookup().unreflect(method).bindTo(instance);
|
this.methodHandle = MethodHandles.lookup().unreflect(method).bindTo(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,4 +79,12 @@ public class MethodArgumentParser<C, T> implements ArgumentParser<C, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull List<@NonNull String> suggestions(
|
||||||
|
final @NonNull CommandContext<C> commandContext,
|
||||||
|
final @NonNull String input
|
||||||
|
) {
|
||||||
|
return this.suggestionProvider.apply(commandContext, input);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This annotation allows you to create annotated methods that behave like argument parsers.
|
* This annotation allows you to create annotated methods that behave like argument parsers.
|
||||||
|
|
@ -52,4 +53,18 @@ public @interface Parser {
|
||||||
*/
|
*/
|
||||||
String name() default "";
|
String name() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the suggestions provider to use. If the string is left empty, the default
|
||||||
|
* provider for the {@link cloud.commandframework.annotations.Argument} will be used. Otherwise,
|
||||||
|
* the {@link cloud.commandframework.arguments.parser.ParserRegistry} instance in the
|
||||||
|
* {@link cloud.commandframework.CommandManager} will be queried for a matching suggestion provider.
|
||||||
|
* <p>
|
||||||
|
* For this to work, the suggestion needs to be registered in the parser registry. To do this, use
|
||||||
|
* {@link cloud.commandframework.arguments.parser.ParserRegistry#registerSuggestionProvider(String, BiFunction)}.
|
||||||
|
* The registry instance can be retrieved using {@link cloud.commandframework.CommandManager#getParserRegistry()}.
|
||||||
|
*
|
||||||
|
* @return The name of the suggestion provider, or {@code ""}
|
||||||
|
*/
|
||||||
|
String suggestions() default "";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -153,13 +153,18 @@ class AnnotationParserTest {
|
||||||
TypeToken.get(CustomType.class),
|
TypeToken.get(CustomType.class),
|
||||||
ParserParameters.empty()
|
ParserParameters.empty()
|
||||||
).orElseThrow(() -> new NullPointerException("Could not find CustomType parser"));
|
).orElseThrow(() -> new NullPointerException("Could not find CustomType parser"));
|
||||||
Assertions.assertEquals("yay", parser.parse(
|
final CommandContext<TestCommandSender> context = new CommandContext<>(
|
||||||
new CommandContext<>(
|
|
||||||
new TestCommandSender(),
|
new TestCommandSender(),
|
||||||
this.manager
|
this.manager
|
||||||
),
|
);
|
||||||
|
Assertions.assertEquals("yay", parser.parse(
|
||||||
|
context,
|
||||||
new LinkedList<>()
|
new LinkedList<>()
|
||||||
).getParsedValue().orElse(new CustomType("")).toString());
|
).getParsedValue().orElse(new CustomType("")).toString());
|
||||||
|
Assertions.assertTrue(parser.suggestions(
|
||||||
|
context,
|
||||||
|
""
|
||||||
|
).contains("Stella"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suggestions("cows")
|
@Suggestions("cows")
|
||||||
|
|
@ -167,7 +172,7 @@ class AnnotationParserTest {
|
||||||
return Arrays.asList("Stella", "Bella", "Agda");
|
return Arrays.asList("Stella", "Bella", "Agda");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Parser
|
@Parser(suggestions = "cows")
|
||||||
public CustomType customTypeParser(final CommandContext<TestCommandSender> context, final Queue<String> input) {
|
public CustomType customTypeParser(final CommandContext<TestCommandSender> context, final Queue<String> input) {
|
||||||
return new CustomType("yay");
|
return new CustomType("yay");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue