ArgParser.java

package net.morimekta.terminal.args;

import net.morimekta.collect.UnmodifiableList;
import net.morimekta.strings.NamingUtil;
import net.morimekta.terminal.args.impl.ArgParserImpl;

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

public interface ArgParser {
    /**
     * @param program     The program name for the argument parser.
     * @param version     The program version.
     * @param description The program description.
     * @return The argument parser builder.
     */
    static ArgParser.Builder argParser(String program, String version, String description) {
        return new ArgParserImpl.BuilderImpl(null, program, version, description);
    }

    /**
     * The name of the program. Should be essentially what the user types on
     * the command line to invoke the program.
     *
     * @return The program name.
     */
    String getProgram();

    /**
     * The program version string.
     *
     * @return The program version.
     */
    String getVersion();

    /**
     * Short description of the program. Should be the string that is shown
     * on the top of the program usage help, usually just a few words. Should
     * be capitalized.
     *
     * @return The program description.
     */
    String getDescription();

    /**
     * @return The parent argument parser if any.
     */
    ArgParser getParent();

    /**
     * @return List of options on the argument parser.
     */
    List<Option> getOptions();

    /**
     * @return List of arguments on the argument parser.
     */
    List<Arg> getArguments();

    /**
     * @param <SubCommandDef> The subcommand definition.
     * @return The set of subcommands. Null of subcommands not configured.
     */
    <SubCommandDef> SubCommandSet<SubCommandDef> getSubCommandSet();

    /**
     * Validate all options and arguments.
     */
    void validate() throws ArgException;

    /**
     * Parse arguments from the main method.
     *
     * @param args The argument list.
     * @return The argument parser.
     */
    ArgParser parse(List<String> args);

    /**
     * Parse arguments from the main method.
     *
     * @param args The argument list.
     * @return The argument parser.
     */
    default ArgParser parse(String... args) {
        return parse(UnmodifiableList.asList(args));
    }

    /**
     * Builder for an argument parser.
     */
    interface Builder extends ArgParserBuilder {
        /**
         * An argument
         *
         * @param arg The argument to add.
         * @param <A> The base argument type.
         * @return The argument parser builder.
         */
        <A extends Arg> Builder add(A arg);

        /**
         * Add an argument builder.
         *
         * @param argBuilder The argument to add.
         * @param <A>        The base argument type.
         * @return The argument parser builder.
         */
        <A extends Arg> Builder add(Arg.Builder<A> argBuilder);

        /**
         * Which naming format to use as default for generating flag names.
         *
         * @param format The maing format.
         * @return The argument parser builder.
         */
        Builder generateArgsNameFormat(ArgNameFormat format);

        /**
         * Generate arguments to fill in the POJO config object.
         *
         * @param config The config object to fill in.
         * @return The argument parser builder.
         */
        Builder generateArgs(Object config);

        /**
         * Start adding sub-commands, and get the sub-command builder. The
         * sub-command-set method can only be called once.
         *
         * @param name            Name to for sub-command name in short usage.
         * @param usage           Usage string for sub-commands.
         * @param consumer        Consumer to accept subcommand after parsing.
         * @param <SubCommandDef> The subcommand type.
         * @return The sub-command builder.
         */
        <SubCommandDef> SubCommandSet.Builder<SubCommandDef> withSubCommands(
                String name,
                String usage,
                Consumer<SubCommandDef> consumer);
    }
}