Skip to content

Syntax arguments are overly verbose. #68

@ProdPreva1l

Description

@ProdPreva1l

In my opinion, adding an argument to a syntax is too verbose and could be cleaner.

Extended Commands

In an extended command for a custom argument processor we have to do the following

Custom Argument Processor (Extended Command)
@Override
public void provide(@NotNull BaseCommand<?> command) {
    command.addSubCommand("flavor", (sub) -> sub.addSyntax((ctx) -> {
        final CommandUser user = sub.getUser(ctx.getSource());
        final IceCreamFlavor flavor = ctx.getArgument("flavor", IceCreamFlavor.class);
        switch (flavor) {
            case VANILLA -> user.getAudience().sendMessage(Component.text("Vanilla ice cream is fine!"));
            case CHOCOLATE -> user.getAudience().sendMessage(Component.text("Chocolate ice cream is kino!"));
            case STRAWBERRY -> user.getAudience().sendMessage(Component.text("Strawberry ice cream is ok..."));
        }
    }, exampleCustomArg()));
}

private static <S> ArgumentElement<S, ExtendedCommand.IceCreamFlavor> exampleCustomArg() {
    return new ArgumentElement<>("flavor", reader -> {
        final String flavor = reader.readString();
        try {
            return IceCreamFlavor.valueOf(flavor.toUpperCase(Locale.ENGLISH));
        } catch (IllegalArgumentException e) {
            throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownArgument().create();
        }
    }, (context, builder) -> {
        Arrays.stream(IceCreamFlavor.values()).forEach(
            flavor -> builder.suggest(flavor.name().toLowerCase(Locale.ENGLISH))
        );
        return builder.buildFuture();
    });
}

enum IceCreamFlavor {
    VANILLA,
    CHOCOLATE,
    STRAWBERRY
}

taking note of having to pass exampleCustomArg() in the addSyntax method

2 things could done to make this look nicer

  1. adding the processor in the registration of uniform itself instead of each subcommand
  2. More specific to this case but, adding a default processor for enums, shouldn't be hard just suggest Enum#name and grab it with Enum.valueOf()

for the first idea it could look something like this
and now that is used whenever an IceCreamFlavor is an argument

Annotated Commands

In an annotated command for an argument we have to do the following

@Syntax
public void pongMessageWithColor(
        CommandUser user,
        @Argument(name = "message", parser = Argument.StringArg.class) String message,
        @Argument(name = "color", parser = ColorArg.class) NamedTextColor color
) {
    // command execution
}

In my opinion this is too verbose for 2 reasons:

  1. having to specify a name, it would make sense to have that as an optional value and use the annotated parameters name by default
  2. again with having to manually specify the Argument processor

there should really be a registry for arg processors like this example usage that automatically applies them based off the argument's class

Registering Custom Argument Processor In Uniform Registration

@Override
public void onEnable() {
    PaperUniform uniform = PaperUniform.getInstance(this);
    // nice and simple registerArgumentProcessor(ClassToProcess, String processor, tab suggester)
    uniform.registerArgumentProcessor(IceCreamFlavour.class, reader -> {
        final String flavor = reader.readString();
        try {
            return IceCreamFlavor.valueOf(flavor.toUpperCase(Locale.ENGLISH));
        } catch (IllegalArgumentException e) {
            throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownArgument().create();
        }
    }, (context, builder) -> {
        Arrays.stream(IceCreamFlavor.values()).forEach(
            flavor -> builder.suggest(flavor.name().toLowerCase(Locale.ENGLISH))
        );
        return builder.buildFuture();
    })
    uniform.register(new ExtendedCommand(), new AnnotatedCommand());
  }

If this is agreed upon i can work on adding this in my spare time.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions