/* * 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 javax.annotation.Nonnull; import javax.annotation.Nullable; import java.nio.ByteBuffer; import java.util.Map; import java.util.Optional; import static dan200.computercraft.api.lua.LuaValues.checkFinite; /** * 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[count()]; for( int i = 0; i < result.length; i++ ) { result[i] = 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) 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 = 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, 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 = 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 = 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( 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 = 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, 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 = 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 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 = 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 = 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 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 = 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 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 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 = 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 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 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 = 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 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 = 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 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 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 = get( index ); if( value == null ) { return Optional.empty(); } if( !(value instanceof Map) ) { throw LuaValues.badArgumentOf( index, "map", value ); } return Optional.of( (Map) value ); } }