core: Use the ArgumentDescription interface for descriptions

This allows minecraft-extras to provide an implementation that
uses Adventure chat components to represent the description.
This commit is contained in:
Zach Levis 2021-01-11 23:08:24 -08:00 committed by Alexander Söderberg
parent fa16fc8ef2
commit b38c725dc5
19 changed files with 903 additions and 94 deletions

View file

@ -0,0 +1,80 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg & Contributors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
package cloud.commandframework;
import cloud.commandframework.arguments.CommandArgument;
import org.checkerframework.checker.nullness.qual.NonNull;
import static java.util.Objects.requireNonNull;
/**
* A description for a {@link CommandArgument}
*
* @since 1.4.0
*/
public interface ArgumentDescription {
/**
* Get an empty command description.
*
* @return Command description
*/
@SuppressWarnings("deprecation")
static @NonNull ArgumentDescription empty() {
return Description.EMPTY;
}
/**
* Create a command description instance.
*
* @param string Command description
* @return Created command description
*/
@SuppressWarnings("deprecation")
static @NonNull ArgumentDescription of(final @NonNull String string) {
if (requireNonNull(string, "string").isEmpty()) {
return Description.EMPTY;
} else {
return new Description(string);
}
}
/**
* Get the plain-text description.
*
* @return Command description
*/
@NonNull String getDescription();
/**
* Get whether or not this description contains contents.
*
* @return if this description is empty or not
*/
default boolean isEmpty() {
return this.getDescription().isEmpty();
}
}

View file

@ -209,6 +209,7 @@ public class Command<C> {
// Converts a map of CommandArgument and Description pairs to a List of CommandComponent
// Used for backwards-compatibility
@SuppressWarnings("deprecation")
private static <C> @NonNull List<@NonNull CommandComponent<C>> mapToComponents(
final @NonNull Map<@NonNull CommandArgument<C, ?>, @NonNull Description> commandArguments
) {
@ -227,12 +228,35 @@ public class Command<C> {
* @param aliases Command aliases
* @param <C> Command sender type
* @return Command builder
* @deprecated for removal since 1.4.0. Use {@link #newBuilder(String, CommandMeta, ArgumentDescription, String...)} instead.
*/
@Deprecated
public static <C> @NonNull Builder<C> newBuilder(
final @NonNull String commandName,
final @NonNull CommandMeta commandMeta,
final @NonNull Description description,
final @NonNull String... aliases
) {
return newBuilder(commandName, commandMeta, (ArgumentDescription) description, aliases);
}
/**
* Create a new command builder. Is recommended to use the builder methods
* in {@link CommandManager} rather than invoking this method directly.
*
* @param commandName Base command argument
* @param commandMeta Command meta instance
* @param description Command description
* @param aliases Command aliases
* @param <C> Command sender type
* @return Command builder
* @since 1.4.0
*/
public static <C> @NonNull Builder<C> newBuilder(
final @NonNull String commandName,
final @NonNull CommandMeta commandMeta,
final @NonNull ArgumentDescription description,
final @NonNull String... aliases
) {
final List<CommandComponent<C>> commands = new ArrayList<>();
commands.add(CommandComponent.of(StaticArgument.of(commandName, aliases), description));
@ -263,7 +287,7 @@ public class Command<C> {
final @NonNull String... aliases
) {
final List<CommandComponent<C>> commands = new ArrayList<>();
commands.add(CommandComponent.of(StaticArgument.of(commandName, aliases), Description.empty()));
commands.add(CommandComponent.of(StaticArgument.of(commandName, aliases), ArgumentDescription.empty()));
return new Builder<>(
null,
commandMeta,
@ -343,7 +367,7 @@ public class Command<C> {
public @NonNull String getArgumentDescription(final @NonNull CommandArgument<C, ?> argument) {
for (final CommandComponent<C> component : this.components) {
if (component.getArgument().equals(argument)) {
return component.getDescription().getDescription();
return component.getArgumentDescription().getDescription();
}
}
throw new IllegalArgumentException("Command argument not found: " + argument);
@ -512,7 +536,9 @@ public class Command<C> {
* @param description Literal description
* @param aliases Argument aliases
* @return New builder instance with the modified command chain
* @deprecated for removal since 1.4.0. Use {@link #literal(String, ArgumentDescription, String...)} instead.
*/
@Deprecated
public @NonNull Builder<C> literal(
final @NonNull String main,
final @NonNull Description description,
@ -521,6 +547,23 @@ public class Command<C> {
return this.argument(StaticArgument.of(main, aliases), description);
}
/**
* Inserts a required {@link StaticArgument} into the command chain
*
* @param main Main argument name
* @param description Literal description
* @param aliases Argument aliases
* @return New builder instance with the modified command chain
* @since 1.4.0
*/
public @NonNull Builder<C> literal(
final @NonNull String main,
final @NonNull ArgumentDescription description,
final @NonNull String... aliases
) {
return this.argument(StaticArgument.of(main, aliases), description);
}
/**
* Add a new command argument with an empty description to the command
*
@ -530,7 +573,7 @@ public class Command<C> {
* @return New builder instance with the command argument inserted into the argument list
*/
public <T> @NonNull Builder<C> argument(final CommandArgument.@NonNull Builder<C, T> builder) {
return this.argument(builder.build(), Description.empty());
return this.argument(builder.build(), ArgumentDescription.empty());
}
/**
@ -541,7 +584,7 @@ public class Command<C> {
* @return New builder instance with the command argument inserted into the argument list
*/
public <T> @NonNull Builder<C> argument(final @NonNull CommandArgument<C, T> argument) {
return this.argument(argument, Description.empty());
return this.argument(argument, ArgumentDescription.empty());
}
/**
@ -551,10 +594,28 @@ public class Command<C> {
* @param description Argument description
* @param <T> Argument type
* @return New builder instance with the command argument inserted into the argument list
* @deprecated for removal since 1.4.0. Use {@link #argument(CommandArgument, ArgumentDescription)} instead.
*/
@Deprecated
public <T> @NonNull Builder<C> argument(
final @NonNull CommandArgument<C, T> argument,
final @NonNull Description description
) {
return this.argument(argument, (ArgumentDescription) description);
}
/**
* Add a new command argument to the command
*
* @param argument Argument to add
* @param description Argument description
* @param <T> Argument type
* @return New builder instance with the command argument inserted into the argument list
* @since 1.4.0
*/
public <T> @NonNull Builder<C> argument(
final @NonNull CommandArgument<C, T> argument,
final @NonNull ArgumentDescription description
) {
if (argument.isArgumentRegistered()) {
throw new IllegalArgumentException("The provided argument has already been associated with a command."
@ -582,10 +643,29 @@ public class Command<C> {
* @param description Argument description
* @param <T> Argument type
* @return New builder instance with the command argument inserted into the argument list
* @deprecated for removal since 1.4.0. Use {@link #argument(CommandArgument.Builder, ArgumentDescription)} instead.
*/
@Deprecated
public <T> @NonNull Builder<C> argument(
final CommandArgument.@NonNull Builder<C, T> builder,
final @NonNull Description description
) {
return this.argument(builder, (ArgumentDescription) description);
}
/**
* Add a new command argument to the command
*
* @param builder Argument to add. {@link CommandArgument.Builder#build()} will be invoked
* and the result will be registered in the command.
* @param description Argument description
* @param <T> Argument type
* @return New builder instance with the command argument inserted into the argument list
* @since 1.4.0
*/
public <T> @NonNull Builder<C> argument(
final CommandArgument.@NonNull Builder<C, T> builder,
final @NonNull ArgumentDescription description
) {
final List<CommandComponent<C>> commandComponents = new ArrayList<>(this.commandComponents);
commandComponents.add(CommandComponent.of(builder.build(), description));
@ -640,12 +720,41 @@ public class Command<C> {
* @param <U> First type
* @param <V> Second type
* @return Builder instance with the argument inserted
* @deprecated for removal since 1.4.0. Use {@link #argumentPair(String, Pair, Pair, ArgumentDescription)} instead.
*/
@Deprecated
public <U, V> @NonNull Builder<C> argumentPair(
final @NonNull String name,
final @NonNull Pair<@NonNull String, @NonNull String> names,
final @NonNull Pair<@NonNull Class<U>, @NonNull Class<V>> parserPair,
final @NonNull Description description
) {
return this.argumentPair(name, names, parserPair, (ArgumentDescription) description);
}
/**
* Create a new argument pair that maps to {@link Pair}
* <p>
* For this to work, there must be a {@link CommandManager}
* attached to the command builder. To guarantee this, it is recommended to get the command builder instance
* using {@link CommandManager#commandBuilder(String, String...)}
*
* @param name Name of the argument
* @param names Pair containing the names of the sub-arguments
* @param parserPair Pair containing the types of the sub-arguments. There must be parsers for these types registered
* in the {@link cloud.commandframework.arguments.parser.ParserRegistry} used by the
* {@link CommandManager} attached to this command
* @param description Description of the argument
* @param <U> First type
* @param <V> Second type
* @return Builder instance with the argument inserted
* @since 1.4.0
*/
public <U, V> @NonNull Builder<C> argumentPair(
final @NonNull String name,
final @NonNull Pair<@NonNull String, @NonNull String> names,
final @NonNull Pair<@NonNull Class<U>, @NonNull Class<V>> parserPair,
final @NonNull ArgumentDescription description
) {
if (this.commandManager == null) {
throw new IllegalStateException("This cannot be called from a command that has no command manager attached");
@ -672,7 +781,10 @@ public class Command<C> {
* @param <V> Second type
* @param <O> Output type
* @return Builder instance with the argument inserted
* @deprecated for removal since 1.4.0. Use
* {@link #argumentPair(String, TypeToken, Pair, Pair, BiFunction, ArgumentDescription)} instead.
*/
@Deprecated
public <U, V, O> @NonNull Builder<C> argumentPair(
final @NonNull String name,
final @NonNull TypeToken<O> outputType,
@ -680,6 +792,38 @@ public class Command<C> {
final @NonNull Pair<Class<U>, Class<V>> parserPair,
final @NonNull BiFunction<C, Pair<U, V>, O> mapper,
final @NonNull Description description
) {
return this.argumentPair(name, outputType, names, parserPair, mapper, (ArgumentDescription) description);
}
/**
* Create a new argument pair that maps to a custom type.
* <p>
* For this to work, there must be a {@link CommandManager}
* attached to the command builder. To guarantee this, it is recommended to get the command builder instance
* using {@link CommandManager#commandBuilder(String, String...)}
*
* @param name Name of the argument
* @param outputType The output type
* @param names Pair containing the names of the sub-arguments
* @param parserPair Pair containing the types of the sub-arguments. There must be parsers for these types registered
* in the {@link cloud.commandframework.arguments.parser.ParserRegistry} used by the
* {@link CommandManager} attached to this command
* @param mapper Mapper that maps from {@link Pair} to the custom type
* @param description Description of the argument
* @param <U> First type
* @param <V> Second type
* @param <O> Output type
* @return Builder instance with the argument inserted
* @since 1.4.0
*/
public <U, V, O> @NonNull Builder<C> argumentPair(
final @NonNull String name,
final @NonNull TypeToken<O> outputType,
final @NonNull Pair<String, String> names,
final @NonNull Pair<Class<U>, Class<V>> parserPair,
final @NonNull BiFunction<C, Pair<U, V>, O> mapper,
final @NonNull ArgumentDescription description
) {
if (this.commandManager == null) {
throw new IllegalStateException("This cannot be called from a command that has no command manager attached");
@ -707,12 +851,43 @@ public class Command<C> {
* @param <V> Second type
* @param <W> Third type
* @return Builder instance with the argument inserted
* @deprecated for removal since 1.4.0. Use {@link #argumentTriplet(String, Triplet, Triplet, ArgumentDescription)}
* instead.
*/
@Deprecated
public <U, V, W> @NonNull Builder<C> argumentTriplet(
final @NonNull String name,
final @NonNull Triplet<String, String, String> names,
final @NonNull Triplet<Class<U>, Class<V>, Class<W>> parserTriplet,
final @NonNull Description description
) {
return this.argumentTriplet(name, names, parserTriplet, (ArgumentDescription) description);
}
/**
* Create a new argument pair that maps to {@link cloud.commandframework.types.tuples.Triplet}
* <p>
* For this to work, there must be a {@link CommandManager}
* attached to the command builder. To guarantee this, it is recommended to get the command builder instance
* using {@link CommandManager#commandBuilder(String, String...)}
*
* @param name Name of the argument
* @param names Triplet containing the names of the sub-arguments
* @param parserTriplet Triplet containing the types of the sub-arguments. There must be parsers for these types
* registered in the {@link cloud.commandframework.arguments.parser.ParserRegistry}
* used by the {@link CommandManager} attached to this command
* @param description Description of the argument
* @param <U> First type
* @param <V> Second type
* @param <W> Third type
* @return Builder instance with the argument inserted
* @since 1.4.0
*/
public <U, V, W> @NonNull Builder<C> argumentTriplet(
final @NonNull String name,
final @NonNull Triplet<String, String, String> names,
final @NonNull Triplet<Class<U>, Class<V>, Class<W>> parserTriplet,
final @NonNull ArgumentDescription description
) {
if (this.commandManager == null) {
throw new IllegalStateException("This cannot be called from a command that has no command manager attached");
@ -740,15 +915,57 @@ public class Command<C> {
* @param <W> Third type
* @param <O> Output type
* @return Builder instance with the argument inserted
* @deprecated for removal since 1.4.0, use
* {@link #argumentTriplet(String, TypeToken, Triplet, Triplet, BiFunction, ArgumentDescription)} instead.
*/
@Deprecated
public <U, V, W, O> @NonNull Builder<C> argumentTriplet(
final @NonNull String name,
final @NonNull TypeToken<O> outputType,
final @NonNull Triplet<String, String, String> names,
final @NonNull Triplet<Class<U>, Class<V>, Class<W>> parserTriplet,
final @NonNull BiFunction<C, Triplet<U, V, W>, O> mapper,
final @NonNull Description description
) {
return this.argumentTriplet(
name,
outputType,
names,
parserTriplet,
mapper,
(ArgumentDescription) description
);
}
/**
* Create a new argument triplet that maps to a custom type.
* <p>
* For this to work, there must be a {@link CommandManager}
* attached to the command builder. To guarantee this, it is recommended to get the command builder instance
* using {@link CommandManager#commandBuilder(String, String...)}
*
* @param name Name of the argument
* @param outputType The output type
* @param names Triplet containing the names of the sub-arguments
* @param parserTriplet Triplet containing the types of the sub-arguments. There must be parsers for these types
* registered in the {@link cloud.commandframework.arguments.parser.ParserRegistry} used by
* the {@link CommandManager} attached to this command
* @param mapper Mapper that maps from {@link Triplet} to the custom type
* @param description Description of the argument
* @param <U> First type
* @param <V> Second type
* @param <W> Third type
* @param <O> Output type
* @return Builder instance with the argument inserted
* @since 1.4.0
*/
public <U, V, W, O> @NonNull Builder<C> argumentTriplet(
final @NonNull String name,
final @NonNull TypeToken<O> outputType,
final @NonNull Triplet<String, String, String> names,
final @NonNull Triplet<Class<U>, Class<V>,
Class<W>> parserTriplet,
final @NonNull Triplet<Class<U>, Class<V>, Class<W>> parserTriplet,
final @NonNull BiFunction<C, Triplet<U, V, W>, O> mapper,
final @NonNull Description description
final @NonNull ArgumentDescription description
) {
if (this.commandManager == null) {
throw new IllegalStateException("This cannot be called from a command that has no command manager attached");
@ -852,7 +1069,7 @@ public class Command<C> {
continue;
}
final CommandArgument<C, ?> builtArgument = argument.copy();
builder = builder.argument(builtArgument, component.getDescription());
builder = builder.argument(builtArgument, component.getArgumentDescription());
}
if (this.commandPermission.toString().isEmpty()) {
builder = builder.permission(command.getCommandPermission());
@ -910,9 +1127,9 @@ public class Command<C> {
public @NonNull Command<C> build() {
final List<CommandComponent<C>> commandComponents = new ArrayList<>(this.commandComponents);
/* Construct flag node */
if (!flags.isEmpty()) {
if (!this.flags.isEmpty()) {
final FlagArgument<C> flagArgument = new FlagArgument<>(this.flags);
commandComponents.add(CommandComponent.of(flagArgument, Description.of("Command flags")));
commandComponents.add(CommandComponent.of(flagArgument, ArgumentDescription.of("Command flags")));
}
return new Command<>(
Collections.unmodifiableList(commandComponents),

View file

@ -37,7 +37,7 @@ import java.util.Objects;
public final class CommandComponent<C> {
private final CommandArgument<C, ?> argument;
private final Description description;
private final ArgumentDescription description;
/**
* Initializes a new CommandComponent
@ -47,7 +47,7 @@ public final class CommandComponent<C> {
*/
private CommandComponent(
final @NonNull CommandArgument<C, ?> commandArgument,
final @NonNull Description commandDescription
final @NonNull ArgumentDescription commandDescription
) {
this.argument = commandArgument;
this.description = commandDescription;
@ -66,14 +66,30 @@ public final class CommandComponent<C> {
* Gets the command component description
*
* @return command component description
* @deprecated for removal since 1.4.0. Use {@link #getArgumentDescription()} instead.
*/
@Deprecated
public @NonNull Description getDescription() {
if (this.description instanceof Description) {
return (Description) this.description;
} else {
return new Description(this.description.getDescription());
}
}
/**
* Gets the command component description
*
* @return command component description
* @since 1.4.0
*/
public @NonNull ArgumentDescription getArgumentDescription() {
return this.description;
}
@Override
public int hashCode() {
return Objects.hash(getArgument(), getDescription());
return Objects.hash(this.getArgument(), this.getArgumentDescription());
}
@Override
@ -81,9 +97,9 @@ public final class CommandComponent<C> {
if (this == o) {
return true;
} else if (o instanceof CommandComponent) {
CommandComponent<?> that = (CommandComponent<?>) o;
return getArgument().equals(that.getArgument())
&& getDescription().equals(that.getDescription());
final CommandComponent<?> that = (CommandComponent<?>) o;
return this.getArgument().equals(that.getArgument())
&& this.getArgumentDescription().equals(that.getArgumentDescription());
} else {
return false;
}
@ -102,11 +118,28 @@ public final class CommandComponent<C> {
* @param commandArgument Command Component Argument
* @param commandDescription Command Component Description
* @return new CommandComponent
* @deprecated for removal since 1.4.0. Use {@link #of(CommandArgument, ArgumentDescription)} instead.
*/
@Deprecated
public static <C> @NonNull CommandComponent<C> of(
final @NonNull CommandArgument<C, ?> commandArgument,
final @NonNull Description commandDescription
) {
return new CommandComponent<C>(commandArgument, commandDescription);
}
/**
* Creates a new CommandComponent with the provided argument and description
*
* @param <C> Command sender type
* @param commandArgument Command Component Argument
* @param commandDescription Command Component Description
* @return new CommandComponent
*/
public static <C> @NonNull CommandComponent<C> of(
final @NonNull CommandArgument<C, ?> commandArgument,
final @NonNull ArgumentDescription commandDescription
) {
return new CommandComponent<C>(commandArgument, commandDescription);
}
}

View file

@ -353,12 +353,40 @@ public abstract class CommandManager<C> {
* @param description Description for the root literal
* @param meta Command meta
* @return Builder instance
* @deprecated for removal since 1.4.0. Use {@link #commandBuilder(String, Collection, Description, CommandMeta)} instead.
*/
@Deprecated
public Command.@NonNull Builder<C> commandBuilder(
final @NonNull String name,
final @NonNull Collection<String> aliases,
final @NonNull Description description,
final @NonNull CommandMeta meta
) {
return commandBuilder(name, aliases, (ArgumentDescription) description, meta);
}
/**
* Create a new command builder. This will also register the creating manager in the command
* builder using {@link Command.Builder#manager(CommandManager)}, so that the command
* builder is associated with the creating manager. This allows for parser inference based on
* the type, with the help of the {@link ParserRegistry parser registry}
* <p>
* This method will not register the command in the manager. To do that, {@link #command(Command.Builder)}
* or {@link #command(Command)} has to be invoked with either the {@link Command.Builder} instance, or the constructed
* {@link Command command} instance
*
* @param name Command name
* @param aliases Command aliases
* @param description Description for the root literal
* @param meta Command meta
* @return Builder instance
* @since 1.4.0
*/
public Command.@NonNull Builder<C> commandBuilder(
final @NonNull String name,
final @NonNull Collection<String> aliases,
final @NonNull ArgumentDescription description,
final @NonNull CommandMeta meta
) {
return Command.<C>newBuilder(
name,
@ -393,7 +421,7 @@ public abstract class CommandManager<C> {
return Command.<C>newBuilder(
name,
meta,
Description.empty(),
ArgumentDescription.empty(),
aliases.toArray(new String[0])
).manager(this);
}
@ -413,12 +441,41 @@ public abstract class CommandManager<C> {
* @param description Description for the root literal
* @param aliases Command aliases
* @return Builder instance
* @deprecated for removal since 1.4.0. Use {@link #commandBuilder(String, CommandMeta, ArgumentDescription, String...)}
* instead.
*/
@Deprecated
public Command.@NonNull Builder<C> commandBuilder(
final @NonNull String name,
final @NonNull CommandMeta meta,
final @NonNull Description description,
final @NonNull String... aliases
) {
return this.commandBuilder(name, meta, (ArgumentDescription) description, aliases);
}
/**
* Create a new command builder. This will also register the creating manager in the command
* builder using {@link Command.Builder#manager(CommandManager)}, so that the command
* builder is associated with the creating manager. This allows for parser inference based on
* the type, with the help of the {@link ParserRegistry parser registry}
* <p>
* This method will not register the command in the manager. To do that, {@link #command(Command.Builder)}
* or {@link #command(Command)} has to be invoked with either the {@link Command.Builder} instance, or the constructed
* {@link Command command} instance
*
* @param name Command name
* @param meta Command meta
* @param description Description for the root literal
* @param aliases Command aliases
* @return Builder instance
* @since 1.4.0
*/
public Command.@NonNull Builder<C> commandBuilder(
final @NonNull String name,
final @NonNull CommandMeta meta,
final @NonNull ArgumentDescription description,
final @NonNull String... aliases
) {
return Command.<C>newBuilder(
name,
@ -453,7 +510,7 @@ public abstract class CommandManager<C> {
return Command.<C>newBuilder(
name,
meta,
Description.empty(),
ArgumentDescription.empty(),
aliases
).manager(this);
}
@ -476,11 +533,41 @@ public abstract class CommandManager<C> {
* @return Builder instance
* @throws UnsupportedOperationException If the command manager does not support default command meta creation
* @see #createDefaultCommandMeta() Default command meta creation
* @deprecated for removal since 1.4.0. Use {@link #commandBuilder(String, ArgumentDescription, String...)} instead.
*/
@Deprecated
public Command.@NonNull Builder<C> commandBuilder(
final @NonNull String name,
final @NonNull Description description,
final @NonNull String... aliases
) {
return this.commandBuilder(name, (ArgumentDescription) description, aliases);
}
/**
* Create a new command builder using default command meta created by {@link #createDefaultCommandMeta()}.
* <p>
* This will also register the creating manager in the command
* builder using {@link Command.Builder#manager(CommandManager)}, so that the command
* builder is associated with the creating manager. This allows for parser inference based on
* the type, with the help of the {@link ParserRegistry parser registry}
* <p>
* This method will not register the command in the manager. To do that, {@link #command(Command.Builder)}
* or {@link #command(Command)} has to be invoked with either the {@link Command.Builder} instance, or the constructed
* {@link Command command} instance
*
* @param name Command name
* @param description Description for the root literal
* @param aliases Command aliases
* @return Builder instance
* @throws UnsupportedOperationException If the command manager does not support default command meta creation
* @see #createDefaultCommandMeta() Default command meta creation
* @since 1.4.0
*/
public Command.@NonNull Builder<C> commandBuilder(
final @NonNull String name,
final @NonNull ArgumentDescription description,
final @NonNull String... aliases
) {
return Command.<C>newBuilder(
name,
@ -516,7 +603,7 @@ public abstract class CommandManager<C> {
return Command.<C>newBuilder(
name,
this.createDefaultCommandMeta(),
Description.empty(),
ArgumentDescription.empty(),
aliases
).manager(this);
}

View file

@ -28,17 +28,20 @@ import org.checkerframework.checker.nullness.qual.NonNull;
/**
* {@link CommandArgument} description
*
* @deprecated to become package-private since 1.4.0. Use {@link ArgumentDescription} instead.
*/
public final class Description {
@Deprecated
public final class Description implements ArgumentDescription {
/**
* Empty command description
*/
private static final Description EMPTY = Description.of("");
static final Description EMPTY = new Description("");
private final String description;
private Description(final @NonNull String description) {
Description(final @NonNull String description) {
this.description = description;
}
@ -46,7 +49,9 @@ public final class Description {
* Get an empty command description
*
* @return Command description
* @deprecated for removal since 1.4.0. See {@link ArgumentDescription#empty()}
*/
@Deprecated
public static @NonNull Description empty() {
return EMPTY;
}
@ -56,7 +61,9 @@ public final class Description {
*
* @param string Command description
* @return Created command description
* @deprecated for removal since 1.4.0. See {@link ArgumentDescription#of(String)}
*/
@Deprecated
public static @NonNull Description of(final @NonNull String string) {
return new Description(string);
}
@ -66,6 +73,7 @@ public final class Description {
*
* @return Command description
*/
@Override
public @NonNull String getDescription() {
return this.description;
}

View file

@ -23,7 +23,7 @@
//
package cloud.commandframework.arguments.flags;
import cloud.commandframework.Description;
import cloud.commandframework.ArgumentDescription;
import cloud.commandframework.arguments.CommandArgument;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -46,14 +46,14 @@ public final class CommandFlag<T> {
private final @NonNull String name;
private final @NonNull String @NonNull [] aliases;
private final @NonNull Description description;
private final @NonNull ArgumentDescription description;
private final @Nullable CommandArgument<?, T> commandArgument;
private CommandFlag(
final @NonNull String name,
final @NonNull String @NonNull [] aliases,
final @NonNull Description description,
final @NonNull ArgumentDescription description,
final @Nullable CommandArgument<?, T> commandArgument
) {
this.name = Objects.requireNonNull(name, "name cannot be null");
@ -95,8 +95,24 @@ public final class CommandFlag<T> {
* <p>
*
* @return Flag description
* @deprecated for removal since 1.4.0. Use {@link #getArgumentDescription()} instead.
*/
public @NonNull Description getDescription() {
@Deprecated
public cloud.commandframework.@NonNull Description getDescription() {
if (this.description instanceof cloud.commandframework.Description) {
return ((cloud.commandframework.Description) this.description);
} else {
return cloud.commandframework.Description.of(this.description.getDescription());
}
}
/**
* Get the flag description.
*
* @return Flag description
* @since 1.4.0
*/
public @NonNull ArgumentDescription getArgumentDescription() {
return this.description;
}
@ -119,16 +135,16 @@ public final class CommandFlag<T> {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
if (o == null || this.getClass() != o.getClass()) {
return false;
}
final CommandFlag<?> that = (CommandFlag<?>) o;
return getName().equals(that.getName());
return this.getName().equals(that.getName());
}
@Override
public int hashCode() {
return Objects.hash(getName());
return Objects.hash(this.getName());
}
@ -136,13 +152,13 @@ public final class CommandFlag<T> {
private final String name;
private final String[] aliases;
private final Description description;
private final ArgumentDescription description;
private final CommandArgument<?, T> commandArgument;
private Builder(
final @NonNull String name,
final @NonNull String[] aliases,
final @NonNull Description description,
final @NonNull ArgumentDescription description,
final @Nullable CommandArgument<?, T> commandArgument
) {
this.name = name;
@ -152,7 +168,7 @@ public final class CommandFlag<T> {
}
private Builder(final @NonNull String name) {
this(name, new String[0], Description.empty(), null);
this(name, new String[0], ArgumentDescription.empty(), null);
}
/**
@ -191,8 +207,21 @@ public final class CommandFlag<T> {
*
* @param description Flag description
* @return New builder instance
* @deprecated for removal since 1.4.0. Use {@link #withDescription(ArgumentDescription)} instead.
*/
public Builder<T> withDescription(final @NonNull Description description) {
@Deprecated
public Builder<T> withDescription(final cloud.commandframework.@NonNull Description description) {
return this.withDescription((ArgumentDescription) description);
}
/**d
* Create a new builder instance using the given flag description
*
* @param description Flag description
* @return New builder instance
* @since 1.4.0
*/
public Builder<T> withDescription(final @NonNull ArgumentDescription description) {
return new Builder<>(this.name, this.aliases, description, this.commandArgument);
}

View file

@ -52,13 +52,13 @@ class CommandHelpHandlerTest {
manager.command(manager.commandBuilder("test", meta1).literal("this").literal("thing").build());
final SimpleCommandMeta meta2 = SimpleCommandMeta.builder().with(CommandMeta.DESCRIPTION, "Command with variables").build();
manager.command(manager.commandBuilder("test", meta2).literal("int").
argument(IntegerArgument.of("int"), Description.of("A number")).build());
argument(IntegerArgument.of("int"), ArgumentDescription.of("A number")).build());
manager.command(manager.commandBuilder("test").argument(StringArgument.of("potato")));
manager.command(manager.commandBuilder("vec")
.meta(CommandMeta.DESCRIPTION, "Takes in a vector")
.argumentPair("vec", Pair.of("x", "y"),
Pair.of(Double.class, Double.class), Description.of("Vector")
Pair.of(Double.class, Double.class), ArgumentDescription.of("Vector")
)
.build());
}
@ -241,7 +241,7 @@ class CommandHelpHandlerTest {
while (iterator.hasNext()) {
final CommandComponent<TestCommandSender> component = iterator.next();
String description = component.getDescription().getDescription();
String description = component.getArgumentDescription().getDescription();
if (!description.isEmpty()) {
description = ": " + description;
}

View file

@ -66,13 +66,13 @@ public class CommandSuggestionsTest {
manager.command(manager.commandBuilder("com")
.argumentPair("com", Pair.of("x", "y"), Pair.of(Integer.class, TestEnum.class),
Description.empty()
ArgumentDescription.empty()
)
.argument(IntegerArgument.of("int")));
manager.command(manager.commandBuilder("com2")
.argumentPair("com", Pair.of("x", "enum"),
Pair.of(Integer.class, TestEnum.class), Description.empty()
Pair.of(Integer.class, TestEnum.class), ArgumentDescription.empty()
));
manager.command(manager.commandBuilder("flags")

View file

@ -236,9 +236,9 @@ class CommandTreeTest {
// Create and register a command
Command<TestCommandSender> command = manager.commandBuilder("component")
.literal("literal", "literalalias")
.literal("detail", Description.of("detaildescription"))
.literal("detail", ArgumentDescription.of("detaildescription"))
.argument(CommandArgument.ofType(int.class, "argument"),
Description.of("argumentdescription"))
ArgumentDescription.of("argumentdescription"))
.build();
manager.command(command);
@ -264,10 +264,10 @@ class CommandTreeTest {
Assertions.assertEquals(TypeToken.get(int.class), arguments.get(3).getValueType());
// Check description is set for all components, is empty when not specified
Assertions.assertEquals("", components.get(0).getDescription().getDescription());
Assertions.assertEquals("", components.get(1).getDescription().getDescription());
Assertions.assertEquals("detaildescription", components.get(2).getDescription().getDescription());
Assertions.assertEquals("argumentdescription", components.get(3).getDescription().getDescription());
Assertions.assertEquals("", components.get(0).getArgumentDescription().getDescription());
Assertions.assertEquals("", components.get(1).getArgumentDescription().getDescription());
Assertions.assertEquals("detaildescription", components.get(2).getArgumentDescription().getDescription());
Assertions.assertEquals("argumentdescription", components.get(3).getArgumentDescription().getDescription());
}
@Test