All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.spongepowered.api.command.parameter.ArgumentReader Maven / Gradle / Ivy

The newest version!
/*
 * This file is part of SpongeAPI, licensed under the MIT License (MIT).
 *
 * Copyright (c) SpongePowered 
 * Copyright (c) contributors
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.spongepowered.api.command.parameter;

import com.google.gson.JsonObject;
import net.kyori.adventure.text.Component;
import org.spongepowered.api.ResourceKey;
import org.spongepowered.api.command.exception.ArgumentParseException;
import org.spongepowered.api.command.parameter.managed.ValueParser;
import org.spongepowered.api.command.parameter.managed.clientcompletion.ClientCompletionTypes;
import org.spongepowered.api.data.persistence.DataContainer;

/**
 * An {@link ArgumentReader} allows for sequential reading of an input
 * {@link String}, by providing a "cursor" that advances when part
 * of the {@link String} is read.
 *
 * 

The base {@link ArgumentReader} interface (this) only contains * methods that get the state of the reader. The sub-interfaces, * {@link Immutable} and {@link Mutable} indicate whether the reader * is indicating state or is an active reader.

*/ public interface ArgumentReader { /** * Gets the argument string that is being read by this reader. * * @return The input {@link String} */ String input(); /** * Get the number of characters that have not yet been read. * * @return The length of the remaining string */ int remainingLength(); /** * Gets the length of the input string. * * @return The length of the input string */ int totalLength(); /** * Gets the location of the cursor. * *

If zero, the cursor has not yet read a character. If equal to * {@link #totalLength()}, this cursor is at the end of the string, * and {@link #canRead()} will be {@code false}

* * @return The location of the cursor */ int cursor(); /** * Gets the substring that has already been parsed. * * @return The substring that has been parsed. */ String parsed(); /** * Gets the substring that has yet to be read. * * @return The substring that has yet to be read. */ String remaining(); /** * Gets whether this reader has not finished reading the * input string. * *

This is equivalent to {@link #remainingLength()} > 0

* * @return {@code true} if there are further characters to read. */ boolean canRead(); /** * Gets the character after the cursor if {@link #canRead()} is true. * * @return The next character * @throws IllegalStateException if {@link #canRead()} is false */ char peekCharacter(); /** * Creates an {@link ArgumentParseException} with the provided message, * based on the current state of this object. * *

Note that the exception will not be thrown. It * is up to the caller of this method to throw the exception.

* * @param errorMessage The error message to display * @return The exception */ ArgumentParseException createException(Component errorMessage); /** * Represents a {@link ArgumentReader} where the cursor position cannot be * changed. */ interface Immutable extends ArgumentReader { /** * Get a mutable copy of this {@link ArgumentReader} * * @return A {@link Mutable} version of this reader */ ArgumentReader.Mutable mutable(); } /** * Represents a {@link ArgumentReader} where the cursor may move. */ interface Mutable extends ArgumentReader { /** * Moves the cursor to the next non-whitespace character. The cursor * will not advance if it already refers to a non-whitespace character. */ void skipWhitespace(); /** * Reads a character and advances the cursor by one * * @return The character */ char parseChar(); /** * Attempts to read an {@code int} from the input starting at the cursor * position. The cursor will advance until it finds a non-number and * will return an {@code int} based on the consumed string. * *

Numbers may begin with "-" to indicate a negative number

* *

When using this in your parser, you should set * {@link ValueParser#clientCompletionType()} to * {@link ClientCompletionTypes#WHOLE_NUMBER} to tell the client that * the client completion should be an integer.

* * @return The integer * @throws ArgumentParseException if the cursor is not at a number * character */ int parseInt() throws ArgumentParseException; /** * Attempts to read a {@code double} from the input starting at the cursor * position. The cursor will advance until it finds a non-number and * will return a {@code double} based on the consumed string. * *

Numbers may begin with "-" to indicate a negative number, and one * period (".") may be present in the string.

* *

When using this in your parser, you should set * {@link ValueParser#clientCompletionType()} to * {@link ClientCompletionTypes#DECIMAL_NUMBER} to tell the client that * the client completion should be a floating point number.

* * @return The double * @throws ArgumentParseException if the cursor is not at a number * character */ double parseDouble() throws ArgumentParseException; /** * Attempts to read a {@code float} from the input starting at the cursor * position. The cursor will advance until it finds a non-number and * will return a {@code float} based on the consumed string. * *

Numbers may begin with "-" to indicate a negative number, and one * period (".") may be present in the string.

* *

When using this in your parser, you should set * {@link ValueParser#clientCompletionType()} to * {@link ClientCompletionTypes#DECIMAL_NUMBER} to tell the client that * the client completion should be a floating point number.

* * @return The double * @throws ArgumentParseException if the cursor is not at a number * character */ float parseFloat() throws ArgumentParseException; /** * Attempts to read a string that is in a {@link ResourceKey} format, * which is {@code namespace:identifier}. * *

This parser is a strict parser. If the input is * not of the format specified above, this will fail. If you are * potentially expecting a non-namespaced key, but would like to accept * such strings with a default namespace, use * {@link #parseResourceKey(String)}

* *

When using this in your parser, you should set * {@link ValueParser#clientCompletionType()} to * {@link ClientCompletionTypes#RESOURCE_KEY} to tell the client that * the client completion should be a {@link ResourceKey}, so that your * users will not be told to put their argument in quotation marks.

* * @return The {@link ResourceKey} * @throws ArgumentParseException if a key could not be parsed */ ResourceKey parseResourceKey() throws ArgumentParseException; /** * Attempts to read a string that is in a {@link ResourceKey} format, * which is {@code namespace:identifier}. * *

If no colon is encountered, the default namespace defined below * will be used as the namespace.

* *

When using this in your parser, you should set * {@link ValueParser#clientCompletionType()} to * {@link ClientCompletionTypes#RESOURCE_KEY} to tell the client that * the client completion should be a {@link ResourceKey}, so that your * users will not be told to put their argument in quotation marks.

* * @param defaultNamespace The default namespace to use when parsing a * string that does not contain a colon. * @return The {@link ResourceKey} * @throws ArgumentParseException if a key could not be parsed */ ResourceKey parseResourceKey(String defaultNamespace) throws ArgumentParseException; /** * Gets the next word in the input from the position of the cursor. This * will return a string that contains the characters up to, but * excluding, whitespace. The cursor will then be moved to the * whitespace after the word. * *

As an example, if the input string is {@code eggs bacon spam} and * the cursor is at position zero (at the beginning), after this * operation, the cursor will be at the whitespace between "eggs" and * "bacon".

* *

In general, you will likely wish to use {@link #parseString()} * instead unless you are expecting a double quote * mark at the beginning of your string and this is part of the * argument you wish to return.

* *

The following characters will be parsed as part of a valid string * without the need for quotation marks.

* *
    *
  • Alphanumeric symbols
  • *
  • Underscores (_)
  • *
  • Hyphens (-)
  • *
  • Periods (.)
  • *
  • Plus signs (+)
  • *
* *

If you require other symbols, use {@link #parseString()} and ensure * that users are aware they need to surround their inputs with double * quotation marks. Alternatively, consider whether other parse types are * suitable (for example, if you are expecting a {@link ResourceKey}, use * {@link #parseResourceKey()} or {@link #parseResourceKey(String)}.

* * @return The parsed {@link String} * @throws ArgumentParseException if a {@link String} could not be read */ String parseUnquotedString() throws ArgumentParseException; /** * Gets a {@link String} from the position of the cursor. The parsing of * the argument depends on whether a double quote mark is the next character * to be consumed. * *
    *
  • If a double quote is at the beginning of the string * , the parser will read characters until a second * quotation mark is found and return the string between * the two marks. The cursor will then be set to the position after * the second mark.
  • *
  • If the first character is not a double quote * , {@link #parseUnquotedString()} will parse the string *
  • *
* *

If part of the string is quoted, such as {@code "eggs bacon" spam}, * this method will return {@code eggs bacon} on first invocation, then * (after running {@link #skipWhitespace()}, {@code spam} on the second. *

* * @return The parsed {@link String} * @throws ArgumentParseException if a {@link String} could not be read */ String parseString() throws ArgumentParseException; /** * Returns the next {@link String} but does not advance the reader. * *

This call will return the same result as {@link #parseString()}. * Calling this multiple times in succession will return the same result * each time until another parse* method or * {@link #setState(ArgumentReader)} is called.

* * @return The next string to be read * @throws ArgumentParseException if a {@link String} could not be read */ String peekString() throws ArgumentParseException; /** * Parses "true" or "false", else throws an exception. * * @return A {@code boolean} * @throws ArgumentParseException if a {@code boolean} could not be read */ boolean parseBoolean() throws ArgumentParseException; /** * Parses a SNBT string, returning that string. * *

When using this in your parser, you should set * {@link ValueParser#clientCompletionType()} to * {@link ClientCompletionTypes#SNBT} to tell the client that * the client completion should be a SNBT string.

* * @return The string * @throws ArgumentParseException if a SNBT string could not be read */ String parseNBTString() throws ArgumentParseException; /** * Parses a {@link DataContainer}, from a SNBT string, else throws an exception. * *

When using this in your parser, you should set * {@link ValueParser#clientCompletionType()} to * {@link ClientCompletionTypes#SNBT} to tell the client that * the client completion should be a string in Mojang's SNBT format.

* * @return A {@link JsonObject} * @throws ArgumentParseException if a {@link JsonObject} could not be * read */ DataContainer parseDataContainer() throws ArgumentParseException; /** * Returns a immutable copy of the {@link ArgumentReader}. This can be * used to get and restore the state of this reader when coupled with * {@link #setState(ArgumentReader)}. * * @return An {@link Immutable} */ ArgumentReader.Immutable immutable(); /** * Attempts to reset the state of this {@link Mutable} to the state that * the provided {@link ArgumentReader} is in. This is generally used * with {@link #immutable()}. * *

If the provided {@code state} does not have the same * {@link #input()}, this will throw a * {@link IllegalArgumentException}

* * @param state The state to restore this to */ void setState(ArgumentReader state) throws IllegalArgumentException; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy