Lanat Help

Further configuration

As previously mentioned, argument types can not just receive a single value. When creating a new argument type, you can specify how many values it can receive, how many times it can be used, and more.

Value count bounds

Specify how many values the argument type should receive. This is done by overriding the getValueCountBounds method.

@Override public Range getValueCountBounds() { return Range.from(2).to(10); }

In this example, the argument type will require the user to provide at least 2 values, and at most 10.

This will impact the number of values that the argument type can receive when its parseValues method is called.

Usage count bounds

Specify how many times the argument type should be used. This is done by overriding the getUsageCountBounds method.

@Override public Range getUsageCountBounds() { return Range.AT_LEAST_ONE; }

In this example, the argument type will require the user to use it at least once, but it can be used any number of times.

This will impact the number of times the parseValues method will be called. For each time the argument type is used, the parseValues method will be called once with the values provided by the user.

Initial Value

An argument type may specify an initial value by using the proper constructor overload, or by calling the setInitialValue method.

public MyArgumentType() { super(1500); }

In this example, the argument type will have an initial value of 1500.

The initial value is used in cases such as when an argument should always return a value, but the user did not provide one. For instance, the CounterArgumentType always returns a value. If the user never used the argument, it will return the initial value, which is 0.

Name

A short and descriptive name for the argument type. By default, the name is taken from the class name, without the ArgumentType suffix.

@Override public String getName() { return "url"; }
Representation

The representation is a formatted string that visually represents how the argument type behaves in a simple and concise way. By default, the representation is just the name of the argument type.

@Override public TextFormatter getRepresentation() { return TextFormatter.of("url/pointing/to.something", SimpleColor.BRIGHT_MAGENTA) .addFormat(FormatOption.BOLD); }
Description

A detailed description of the argument type. This may appear in the help message when the user requests help for a command.

@Override public String getDescription() { return "A valid URL path pointing to a resource."; }

Registering an argument subtype

An argument type may have subtypes. This is useful when an argument type needs to rely on other argument types to parse its values.

Let's look at the implementation of TupleArgumentType:

public class TupleArgumentType<T> extends ArgumentType<T[]> { private final Range valueCount; private final ArgumentType<T> argumentType; public TupleArgumentType(Range valueCount, ArgumentType<T> argumentType) { this.valueCount = valueCount; this.registerSubType(this.argumentType = argumentType); } ...

TupleArgumentType is a good example of an argument type that has subtypes. It is used to parse any number of values into an array of a specific type. It relies on another argument type to parse the values.

This is how the parseValues method is implemented (simplified):

@Override public T[] parseValues(String[] values) { var result = new Object[values.length]; for (int i = 0; i < values.length; i++) { result[i] = this.argumentType.parseValues(values[i]); } return (T[])result; }
Last modified: 29 May 2024