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 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 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 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 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 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 asClass() { return Boolean.class; } @Override public String getName() { return "Boolean"; } } final record TEnum(@Nullable Class klazz, String name, T[] options) implements Type { public TEnum(Class klazz) { this(klazz, klazz.getSimpleName(), klazz.getEnumConstants()); } public static TEnum create(String name, String[] options) { return new TEnum<>(null, name, options); } @Override public boolean isEnum() { return true; } @Override public Class 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(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(); } } }