Skip to content

Commit

Permalink
added native support for enum constant mapping; adjusted tests
Browse files Browse the repository at this point in the history
  • Loading branch information
BlvckBytes committed Sep 19, 2024
1 parent 5bd97cf commit aa77fe2
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 27 deletions.
31 changes: 24 additions & 7 deletions src/main/java/me/blvckbytes/bbconfigmapper/ConfigMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;

public class ConfigMapper implements IConfigMapper {

Expand Down Expand Up @@ -281,6 +282,22 @@ private Tuple<List<Field>, Iterator<Field>> findApplicableFields(Class<?> type)
return input;
}

if (type.isEnum()) {
String upperInput = input.toString().toUpperCase(Locale.ROOT);
Object[] enumConstants = type.getEnumConstants();

for (Object enumConstant : enumConstants) {
if (((Enum<?>)enumConstant).name().equals(upperInput))
return enumConstant;
}

String existingConstants = Arrays.stream(enumConstants)
.map(it -> ((Enum<?>) it).name())
.collect(Collectors.joining(", "));

throw new MappingError("Value \"" + input + "\" was not one of " + existingConstants);
}

if (AConfigSection.class.isAssignableFrom(type)) {
logger.log(Level.FINEST, () -> DebugLogSource.MAPPER + "Parsing value as config-section");

Expand All @@ -301,28 +318,28 @@ private Tuple<List<Field>, Iterator<Field>> findApplicableFields(Class<?> type)

IEvaluable evaluable = new ConfigValue(input, this.evaluator);

if (type == IEvaluable.class) {
if (IEvaluable.class.isAssignableFrom(type)) {
logger.log(Level.FINEST, () -> DebugLogSource.MAPPER + "Returning evaluable");
return evaluable;
}

if (type == String.class)
return evaluable.<String>asScalar(ScalarType.STRING, GPEEE.EMPTY_ENVIRONMENT);
return evaluable.asScalar(ScalarType.STRING, GPEEE.EMPTY_ENVIRONMENT);

if (type == int.class || type == Integer.class)
return evaluable.<Long>asScalar(ScalarType.LONG, GPEEE.EMPTY_ENVIRONMENT).intValue();
return evaluable.asScalar(ScalarType.LONG, GPEEE.EMPTY_ENVIRONMENT).intValue();

if (type == long.class || type == Long.class)
return evaluable.<Long>asScalar(ScalarType.LONG, GPEEE.EMPTY_ENVIRONMENT);
return evaluable.asScalar(ScalarType.LONG, GPEEE.EMPTY_ENVIRONMENT);

if (type == double.class || type == Double.class)
return evaluable.<Double>asScalar(ScalarType.DOUBLE, GPEEE.EMPTY_ENVIRONMENT);
return evaluable.asScalar(ScalarType.DOUBLE, GPEEE.EMPTY_ENVIRONMENT);

if (type == float.class || type == Float.class)
return evaluable.<Double>asScalar(ScalarType.DOUBLE, GPEEE.EMPTY_ENVIRONMENT).floatValue();
return evaluable.asScalar(ScalarType.DOUBLE, GPEEE.EMPTY_ENVIRONMENT).floatValue();

if (type == boolean.class || type == Boolean.class)
return evaluable.<Boolean>asScalar(ScalarType.BOOLEAN, GPEEE.EMPTY_ENVIRONMENT);
return evaluable.asScalar(ScalarType.BOOLEAN, GPEEE.EMPTY_ENVIRONMENT);

throw new MappingError("Unsupported type specified: " + type);
}
Expand Down
40 changes: 22 additions & 18 deletions src/test/java/me/blvckbytes/bbconfigmapper/ConfigMapperTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
package me.blvckbytes.bbconfigmapper;

import me.blvckbytes.bbconfigmapper.sections.*;
import me.blvckbytes.gpeee.GPEEE;
import org.jetbrains.annotations.Nullable;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -310,39 +309,44 @@ public void shouldIgnoreAnnotatedAndStaticFields() throws Exception {
}

@Test
public void shouldMapValuesUsingTheCustomValueConverter() throws Exception {
IConfigMapper mapper = helper.makeMapper("custom_enum_section.yml", getConverterRegistry());
CustomEnumSection section = mapper.mapSection(null, CustomEnumSection.class);
public void shouldMapEnumValues() throws Exception {
IConfigMapper mapper = helper.makeMapper("enum_section.yml");
EnumSection section = mapper.mapSection(null, EnumSection.class);

assertEquals(ECustomEnum.HELLO, section.getCustomEnumA());
assertEquals(ECustomEnum.WORLD, section.getCustomEnumB());
assertEquals(ECustomEnum.ENUM, section.getCustomEnumC());
assertNull(section.getCustomEnumInvalid());
}

private IValueConverterRegistry getConverterRegistry() {
@Test
public void shouldThrowOnInvalidEnumValues() throws Exception {
IConfigMapper mapper = helper.makeMapper("enum_section_with_invalid.yml");
helper.assertThrowsWithMsg(IllegalStateException.class, () -> mapper.mapSection(null, EnumSection.class), "Value \"INVALID\" was not one of HELLO, WORLD, ENUM (at path 'customEnumInvalid')");
}

@Test
public void shouldMapCustomObject() throws Exception {
IConfigMapper mapper = helper.makeMapper("custom_object.yml", getCustomObjectConverterRegistry());
CustomObjectSection section = mapper.mapSection(null, CustomObjectSection.class);

assertEquals("Hello, world", section.getCustomObject().value);
}

private IValueConverterRegistry getCustomObjectConverterRegistry() {
return new IValueConverterRegistry() {

@Override
public @Nullable Class<?> getRequiredTypeFor(Class<?> type) {
if (type == ECustomEnum.class)
return Object.class;
if (type == CustomObject.class)
return String.class;
return null;
}

@Override
public @Nullable FValueConverter getConverterFor(Class<?> type) {
if (type == ECustomEnum.class) {

return (value, evaluator) -> {
try {
ConfigValue cv = new ConfigValue(value, evaluator);
return ECustomEnum.valueOf(cv.asScalar(ScalarType.STRING, GPEEE.EMPTY_ENVIRONMENT));
} catch (Exception ignored) {}
return null;
};
}

if (type == CustomObject.class)
return (value, evaluator) -> new CustomObject(((String) value));
return null;
}
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package me.blvckbytes.bbconfigmapper.sections;

public class CustomObject {

public final String value;

public CustomObject(String value) {
this.value = value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package me.blvckbytes.bbconfigmapper.sections;

import me.blvckbytes.gpeee.interpreter.EvaluationEnvironmentBuilder;

public class CustomObjectSection extends AConfigSection {

public CustomObject customObject;

public CustomObjectSection(EvaluationEnvironmentBuilder baseEnvironment) {
super(baseEnvironment);
}

public CustomObject getCustomObject() {
return customObject;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@

import me.blvckbytes.gpeee.interpreter.EvaluationEnvironmentBuilder;

public class CustomEnumSection extends AConfigSection {
public class EnumSection extends AConfigSection {

private ECustomEnum customEnumA;
private ECustomEnum customEnumB;
private ECustomEnum customEnumC;
private ECustomEnum customEnumInvalid;

public CustomEnumSection(EvaluationEnvironmentBuilder baseEnvironment) {
public EnumSection(EvaluationEnvironmentBuilder baseEnvironment) {
super(baseEnvironment);
}

Expand Down
1 change: 1 addition & 0 deletions src/test/resources/custom_object.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
customObject: Hello, world
3 changes: 3 additions & 0 deletions src/test/resources/enum_section.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
customEnumA: HELLO
customEnumB: WORLD
customEnumC: ENUM
File renamed without changes.

0 comments on commit aa77fe2

Please sign in to comment.