/* * This file is part of the public ComputerCraft API - http://www.computercraft.info * Copyright Daniel Ratcliffe, 2011-2021. This API may be redistributed unmodified and in full only. * For help using the API, and posting your mods, visit the forums at computercraft.info. */ package dan200.computercraft.api.lua; import static dan200.computercraft.api.lua.LuaValues.checkFinite; import java.nio.ByteBuffer; import java.util.Map; import java.util.Optional; import javax.annotation.Nonnull; import javax.annotation.Nullable; /** * The arguments passed to a function. */ public interface IArguments { /** * Drop a number of arguments. The returned arguments instance will access arguments at position {@code i + count}, rather than {@code i}. However, * errors will still use the given argument index. * * @param count The number of arguments to drop. * @return The new {@link IArguments} instance. */ IArguments drop(int count); default Object[] getAll() { Object[] result = new Object[this.count()]; for (int i = 0; i < result.length; i++) { result[i] = this.get(i); } return result; } /** * Get the number of arguments passed to this function. * * @return The number of passed arguments. */ int count(); /** * Get the argument at the specific index. The returned value must obey the following conversion rules: * * * * @param index The argument number. * @return The argument's value, or {@code null} if not present. */ @Nullable Object get(int index); /** * Get an argument as an integer. * * @param index The argument number. * @return The argument's value. * @throws LuaException If the value is not an integer. */ default int getInt(int index) throws LuaException { return (int) this.getLong(index); } /** * Get an argument as a long. * * @param index The argument number. * @return The argument's value. * @throws LuaException If the value is not a long. */ default long getLong(int index) throws LuaException { Object value = this.get(index); if (!(value instanceof Number)) { throw LuaValues.badArgumentOf(index, "number", value); } return LuaValues.checkFiniteNum(index, (Number) value) .longValue(); } /** * Get an argument as a finite number (not infinite or NaN). * * @param index The argument number. * @return The argument's value. * @throws LuaException If the value is not finite. */ default double getFiniteDouble(int index) throws LuaException { return checkFinite(index, this.getDouble(index)); } /** * Get an argument as a double. * * @param index The argument number. * @return The argument's value. * @throws LuaException If the value is not a number. * @see #getFiniteDouble(int) if you require this to be finite (i.e. not infinite or NaN). */ default double getDouble(int index) throws LuaException { Object value = this.get(index); if (!(value instanceof Number)) { throw LuaValues.badArgumentOf(index, "number", value); } return ((Number) value).doubleValue(); } /** * Get an argument as a boolean. * * @param index The argument number. * @return The argument's value. * @throws LuaException If the value is not a boolean. */ default boolean getBoolean(int index) throws LuaException { Object value = this.get(index); if (!(value instanceof Boolean)) { throw LuaValues.badArgumentOf(index, "boolean", value); } return (Boolean) value; } /** * Get a string argument as a byte array. * * @param index The argument number. * @return The argument's value. This is a read only buffer. * @throws LuaException If the value is not a string. */ @Nonnull default ByteBuffer getBytes(int index) throws LuaException { return LuaValues.encode(this.getString(index)); } /** * Get an argument as a string. * * @param index The argument number. * @return The argument's value. * @throws LuaException If the value is not a string. */ @Nonnull default String getString(int index) throws LuaException { Object value = this.get(index); if (!(value instanceof String)) { throw LuaValues.badArgumentOf(index, "string", value); } return (String) value; } /** * Get a string argument as an enum value. * * @param index The argument number. * @param klass The type of enum to parse. * @param The type of enum to parse. * @return The argument's value. * @throws LuaException If the value is not a string or not a valid option for this enum. */ @Nonnull default > T getEnum(int index, Class klass) throws LuaException { return LuaValues.checkEnum(index, klass, this.getString(index)); } /** * Get an argument as a table. * * @param index The argument number. * @return The argument's value. * @throws LuaException If the value is not a table. */ @Nonnull default Map getTable(int index) throws LuaException { Object value = this.get(index); if (!(value instanceof Map)) { throw LuaValues.badArgumentOf(index, "table", value); } return (Map) value; } /** * Get a string argument as a byte array. * * @param index The argument number. * @return The argument's value, or {@link Optional#empty()} if not present. This is a read only buffer. * @throws LuaException If the value is not a string. */ default Optional optBytes(int index) throws LuaException { return this.optString(index).map(LuaValues::encode); } /** * Get an argument as a string. * * @param index The argument number. * @return The argument's value, or {@link Optional#empty()} if not present. * @throws LuaException If the value is not a string. */ default Optional optString(int index) throws LuaException { Object value = this.get(index); if (value == null) { return Optional.empty(); } if (!(value instanceof String)) { throw LuaValues.badArgumentOf(index, "string", value); } return Optional.of((String) value); } /** * Get a string argument as an enum value. * * @param index The argument number. * @param klass The type of enum to parse. * @param The type of enum to parse. * @return The argument's value. * @throws LuaException If the value is not a string or not a valid option for this enum. */ @Nonnull default > Optional optEnum(int index, Class klass) throws LuaException { Optional str = this.optString(index); return str.isPresent() ? Optional.of(LuaValues.checkEnum(index, klass, str.get())) : Optional.empty(); } /** * Get an argument as a double. * * @param index The argument number. * @param def The default value, if this argument is not given. * @return The argument's value, or {@code def} if none was provided. * @throws LuaException If the value is not a number. */ default double optDouble(int index, double def) throws LuaException { return this.optDouble(index).orElse(def); } /** * Get an argument as a double. * * @param index The argument number. * @return The argument's value, or {@link Optional#empty()} if not present. * @throws LuaException If the value is not a number. */ @Nonnull default Optional optDouble(int index) throws LuaException { Object value = this.get(index); if (value == null) { return Optional.empty(); } if (!(value instanceof Number)) { throw LuaValues.badArgumentOf(index, "number", value); } return Optional.of(((Number) value).doubleValue()); } /** * Get an argument as an int. * * @param index The argument number. * @param def The default value, if this argument is not given. * @return The argument's value, or {@code def} if none was provided. * @throws LuaException If the value is not a number. */ default int optInt(int index, int def) throws LuaException { return this.optInt(index).orElse(def); } /** * Get an argument as an int. * * @param index The argument number. * @return The argument's value, or {@link Optional#empty()} if not present. * @throws LuaException If the value is not a number. */ @Nonnull default Optional optInt(int index) throws LuaException { return this.optLong(index).map(Long::intValue); } /** * Get an argument as a long. * * @param index The argument number. * @return The argument's value, or {@link Optional#empty()} if not present. * @throws LuaException If the value is not a number. */ default Optional optLong(int index) throws LuaException { Object value = this.get(index); if (value == null) { return Optional.empty(); } if (!(value instanceof Number)) { throw LuaValues.badArgumentOf(index, "number", value); } return Optional.of(LuaValues.checkFiniteNum(index, (Number) value) .longValue()); } /** * Get an argument as a long. * * @param index The argument number. * @param def The default value, if this argument is not given. * @return The argument's value, or {@code def} if none was provided. * @throws LuaException If the value is not a number. */ default long optLong(int index, long def) throws LuaException { return this.optLong(index).orElse(def); } /** * Get an argument as a finite number (not infinite or NaN). * * @param index The argument number. * @param def The default value, if this argument is not given. * @return The argument's value, or {@code def} if none was provided. * @throws LuaException If the value is not finite. */ default double optFiniteDouble(int index, double def) throws LuaException { return this.optFiniteDouble(index).orElse(def); } /** * Get an argument as a finite number (not infinite or NaN). * * @param index The argument number. * @return The argument's value, or {@link Optional#empty()} if not present. * @throws LuaException If the value is not finite. */ default Optional optFiniteDouble(int index) throws LuaException { Optional value = this.optDouble(index); if (value.isPresent()) { LuaValues.checkFiniteNum(index, value.get()); } return value; } /** * Get an argument as a boolean. * * @param index The argument number. * @param def The default value, if this argument is not given. * @return The argument's value, or {@code def} if none was provided. * @throws LuaException If the value is not a boolean. */ default boolean optBoolean(int index, boolean def) throws LuaException { return this.optBoolean(index).orElse(def); } /** * Get an argument as a boolean. * * @param index The argument number. * @return The argument's value, or {@link Optional#empty()} if not present. * @throws LuaException If the value is not a boolean. */ default Optional optBoolean(int index) throws LuaException { Object value = this.get(index); if (value == null) { return Optional.empty(); } if (!(value instanceof Boolean)) { throw LuaValues.badArgumentOf(index, "boolean", value); } return Optional.of((Boolean) value); } /** * Get an argument as a string. * * @param index The argument number. * @param def The default value, if this argument is not given. * @return The argument's value, or {@code def} if none was provided. * @throws LuaException If the value is not a string. */ default String optString(int index, String def) throws LuaException { return this.optString(index).orElse(def); } /** * Get an argument as a table. * * @param index The argument number. * @param def The default value, if this argument is not given. * @return The argument's value, or {@code def} if none was provided. * @throws LuaException If the value is not a table. */ default Map optTable(int index, Map def) throws LuaException { return this.optTable(index).orElse(def); } /** * Get an argument as a table. * * @param index The argument number. * @return The argument's value, or {@link Optional#empty()} if not present. * @throws LuaException If the value is not a table. */ default Optional> optTable(int index) throws LuaException { Object value = this.get(index); if (value == null) { return Optional.empty(); } if (!(value instanceof Map)) { throw LuaValues.badArgumentOf(index, "map", value); } return Optional.of((Map) value); } }