001//
002// MIT License
003//
004// Copyright (c) 2021 Alexander Söderberg & Contributors
005//
006// Permission is hereby granted, free of charge, to any person obtaining a copy
007// of this software and associated documentation files (the "Software"), to deal
008// in the Software without restriction, including without limitation the rights
009// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
010// copies of the Software, and to permit persons to whom the Software is
011// furnished to do so, subject to the following conditions:
012//
013// The above copyright notice and this permission notice shall be included in all
014// copies or substantial portions of the Software.
015//
016// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
017// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
018// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
019// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
020// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
021// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
022// SOFTWARE.
023//
024package cloud.commandframework.arguments.parser;
025
026import cloud.commandframework.context.CommandContext;
027import org.checkerframework.checker.nullness.qual.NonNull;
028
029import java.util.Collections;
030import java.util.List;
031import java.util.Queue;
032
033/**
034 * Parser that parses strings into values of a specific type
035 *
036 * @param <C> Command sender type
037 * @param <T> Value type
038 */
039@FunctionalInterface
040public interface ArgumentParser<C, T> {
041
042    /**
043     * Default amount of arguments that the parser expects to consume
044     */
045    int DEFAULT_ARGUMENT_COUNT = 1;
046
047    /**
048     * Parse command input into a command result.
049     * <p>
050     * This method may be called when a command chain is being parsed for execution
051     * (using {@link cloud.commandframework.CommandManager#executeCommand(Object, String)})
052     * or when a command is being parsed to provide context for suggestions
053     * (using {@link cloud.commandframework.CommandManager#suggest(Object, String)}). It is
054     * possible to use {@link CommandContext#isSuggestions()}} to see what the purpose of the
055     * parsing is. Particular care should be taken when parsing for suggestions, as the parsing
056     * method is then likely to be called once for every character written by the command sender.
057     * <p>
058     * This method should never throw any exceptions under normal circumstances. Instead, if the
059     * parsing for some reason cannot be done successfully {@link ArgumentParseResult#failure(Throwable)}
060     * should be returned. This then wraps any exception that should be forwarded to the command sender.
061     * <p>
062     * The parser is assumed to be completely stateless and should not store any information about
063     * the command sender or the command context. Instead, information should be stored in the
064     * {@link CommandContext}.
065     *
066     * @param commandContext Command context
067     * @param inputQueue     The queue of arguments
068     * @return Parsed command result
069     */
070    @NonNull ArgumentParseResult<@NonNull T> parse(
071            @NonNull CommandContext<@NonNull C> commandContext,
072            @NonNull Queue<@NonNull String> inputQueue
073    );
074
075    /**
076     * Get a list of suggested arguments that would be correctly parsed by this parser
077     * <p>
078     * This method is likely to be called for every character provided by the sender and
079     * so it may be necessary to cache results locally to prevent unnecessary computations
080     *
081     * @param commandContext Command context
082     * @param input          Input string
083     * @return List of suggestions
084     */
085    default @NonNull List<@NonNull String> suggestions(
086            final @NonNull CommandContext<C> commandContext,
087            final @NonNull String input
088    ) {
089        return Collections.emptyList();
090    }
091
092    /**
093     * Check whether or not this argument parser is context free. A context free
094     * parser will not use the provided command context, and so supports impromptu parsing
095     *
096     * @return {@code true} if the parser is context free, else {@code false}
097     */
098    default boolean isContextFree() {
099        return false;
100    }
101
102    /**
103     * Get the amount of arguments that this parsers seeks to
104     * consume
105     *
106     * @return The number of arguments tha the parser expects
107     * @since 1.1.0
108     */
109    default int getRequestedArgumentCount() {
110        return DEFAULT_ARGUMENT_COUNT;
111    }
112
113}