Option.java

package net.morimekta.terminal.args;

import net.morimekta.terminal.args.impl.OptionImpl;

import java.util.List;
import java.util.function.Consumer;

import static java.util.Objects.requireNonNull;
import static net.morimekta.terminal.args.impl.OptionUtils.requireValidLongName;
import static net.morimekta.terminal.args.impl.OptionUtils.requireValidShortNames;
import static net.morimekta.terminal.args.impl.OptionUtils.requireValidUsage;

/**
 * Named option that for each invocation takes a single argument value,
 * either the next argument, or from the same argument after a '='
 * delimiter.
 */
public interface Option extends Arg {
    /**
     * Each character of the shortNames string is handled as a short option
     * that is parsed with the -[short] style. If the string is empty or null,
     * no short options are provided.
     *
     * @return The short names
     */
    String getShortNames();

    /**
     * Meta variable to show in usage printout.
     *
     * @return The meta variable.
     */
    String getMetaVar();

    /**
     * When handling a list of short options.
     * <ul>
     *     <li>
     *         If 0 is returned from this method, it should be handled as the
     *         short option char was the only thing being consumed.
     *     </li>
     *     <li>
     *         If 1 is returned from this method, it should be handled as the
     *         remainder of the short options string is consumed.
     *     </li>
     *     <li>
     *         If any higher number is returned, it will consume of the
     *         following arguments from the args list.
     *     </li>
     * </ul>
     *
     * @param opts The remaining characters of the short opt list, including
     *             the triggering char.
     * @param args The list of arguments including the short opt list.
     * @return The number of arguments consumed.
     */
    int applyShort(String opts, List<String> args);

    interface Builder extends Arg.Builder<Option> {
        Builder metaVar(String metaVar);

        Builder defaultValue(Object object);

        Builder repeated();

        Builder required();

        Builder hidden();
    }

    static Builder optionLong(String name,
                              String usage,
                              Consumer<String> consumer) {
        return new OptionImpl.BuilderImpl(
                requireValidLongName(name),
                null,
                requireValidUsage(usage),
                requireNonNull(consumer, "consumer == null"));
    }

    static Builder optionShort(String shortNames,
                               String usage,
                               Consumer<String> consumer) {
        return new OptionImpl.BuilderImpl(
                null,
                requireValidShortNames(shortNames),
                requireValidUsage(usage),
                requireNonNull(consumer, "consumer == null"));
    }

    static Builder option(String name,
                          String shortNames,
                          String usage,
                          Consumer<String> consumer) {
        return new OptionImpl.BuilderImpl(
                requireValidLongName(name),
                requireValidShortNames(shortNames),
                requireValidUsage(usage),
                requireNonNull(consumer, "consumer == null"));
    }
}