LibJF/libjf-config-core-v1/src/main/java/io/gitlab/jfronny/libjf/config/api/v1/type/Type.java

204 lines
4.9 KiB
Java

package io.gitlab.jfronny.libjf.config.api.v1.type;
import org.jetbrains.annotations.Nullable;
/**
* An internal representation of types for the purpose of identifying field types
*/
public sealed interface Type {
static Type ofClass(java.lang.reflect.Type klazz) {
if (klazz == int.class || klazz == Integer.class) return TInt.INSTANCE;
else if (klazz == long.class || klazz == Long.class) return TLong.INSTANCE;
else if (klazz == float.class || klazz == Float.class) return TFloat.INSTANCE;
else if (klazz == double.class || klazz == Double.class) return TDouble.INSTANCE;
else if (klazz == String.class) return TString.INSTANCE;
else if (klazz == boolean.class || klazz == Boolean.class) return TBool.INSTANCE;
else if (klazz instanceof Class<?> k && k.isEnum()) return new TEnum<>(k);
else return new TUnknown<>(klazz);
}
default boolean isInt() {
return false;
}
default boolean isLong() {
return false;
}
default boolean isFloat() {
return false;
}
default boolean isDouble() {
return false;
}
default boolean isString() {
return false;
}
default boolean isBool() {
return false;
}
default boolean isEnum() {
return false;
}
@Nullable java.lang.reflect.Type asClass();
String getName();
final class TInt implements Type {
public static TInt INSTANCE = new TInt();
private TInt() {}
@Override
public boolean isInt() {
return true;
}
@Override
public Class<Integer> asClass() {
return Integer.class;
}
@Override
public String getName() {
return "Integer";
}
}
final class TLong implements Type {
public static TLong INSTANCE = new TLong();
private TLong() {}
@Override
public boolean isLong() {
return true;
}
@Override
public Class<Long> asClass() {
return Long.class;
}
@Override
public String getName() {
return "Long";
}
}
final class TFloat implements Type {
public static TFloat INSTANCE = new TFloat();
private TFloat() {}
@Override
public boolean isFloat() {
return true;
}
@Override
public Class<Float> asClass() {
return Float.class;
}
@Override
public String getName() {
return "Float";
}
}
final class TDouble implements Type {
public static TDouble INSTANCE = new TDouble();
private TDouble() {}
@Override
public boolean isDouble() {
return true;
}
@Override
public Class<Double> asClass() {
return Double.class;
}
@Override
public String getName() {
return "Double";
}
}
final class TString implements Type {
public static TString INSTANCE = new TString();
private TString() {}
@Override
public boolean isString() {
return true;
}
@Override
public Class<String> asClass() {
return String.class;
}
@Override
public String getName() {
return "String";
}
}
final class TBool implements Type {
public static TBool INSTANCE = new TBool();
private TBool() {}
@Override
public boolean isBool() {
return true;
}
@Override
public Class<Boolean> asClass() {
return Boolean.class;
}
@Override
public String getName() {
return "Boolean";
}
}
final record TEnum<T>(@Nullable Class<T> klazz, String name, T[] options) implements Type {
public TEnum(Class<T> klazz) {
this(klazz, klazz.getSimpleName(), klazz.getEnumConstants());
}
public static TEnum<String> create(String name, String[] options) {
return new TEnum<>(null, name, options);
}
@Override
public boolean isEnum() {
return true;
}
@Override
public Class<T> asClass() {
return klazz;
}
@Override
public String getName() {
return name;
}
public T optionForString(String string) {
for (T option : options) {
if (option.toString().equals(string)) return option;
}
return null;
}
}
final record TUnknown<T>(java.lang.reflect.Type klazz) implements Type {
@Override
public @Nullable java.lang.reflect.Type asClass() {
return klazz;
}
@Override
public String getName() {
return klazz instanceof Class<?> k ? k.getSimpleName() : klazz.getTypeName();
}
}
}