Validation fallback values, tests and fixes
This commit is contained in:
@@ -98,7 +98,11 @@ public class DefaultMiddlewareContainer<M> implements MiddlewareContainer<M> {
|
|||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
} catch (AcyclicGraphSorter.GraphCycleException e) {
|
} catch (AcyclicGraphSorter.GraphCycleException e) {
|
||||||
throw new IllegalStateException(e);
|
StringBuilder messageBuilder = new StringBuilder("Found cycle in middleware dependencies: ");
|
||||||
|
e.cycleIndeces().forEach(index -> messageBuilder.append(allMentionedMiddlewareIds[index]).append(" -> "));
|
||||||
|
messageBuilder.append(allMentionedMiddlewareIds[e.cycleIndeces().iterator().next()]);
|
||||||
|
|
||||||
|
throw new IllegalStateException(messageBuilder.toString(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import de.siphalor.tweed5.defaultextensions.validation.api.result.ValidationResu
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.var;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -75,7 +74,6 @@ public class ValidationExtensionImpl implements ReadWriteRelatedExtension, Valid
|
|||||||
|
|
||||||
private RegisteredExtensionData<EntryExtensionsData, InternalValidationEntryData> validationEntryDataExtension;
|
private RegisteredExtensionData<EntryExtensionsData, InternalValidationEntryData> validationEntryDataExtension;
|
||||||
private MiddlewareContainer<ConfigEntryValidator> entryValidatorMiddlewareContainer;
|
private MiddlewareContainer<ConfigEntryValidator> entryValidatorMiddlewareContainer;
|
||||||
private EntryValidationReaderMiddleware readerMiddleware;
|
|
||||||
private RegisteredExtensionData<ReadWriteContextExtensionsData, ValidationIssues> readContextValidationIssuesExtensionData;
|
private RegisteredExtensionData<ReadWriteContextExtensionsData, ValidationIssues> readContextValidationIssuesExtensionData;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -97,8 +95,6 @@ public class ValidationExtensionImpl implements ReadWriteRelatedExtension, Valid
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
entryValidatorMiddlewareContainer.seal();
|
entryValidatorMiddlewareContainer.seal();
|
||||||
|
|
||||||
readerMiddleware = new EntryValidationReaderMiddleware();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -143,7 +139,7 @@ public class ValidationExtensionImpl implements ReadWriteRelatedExtension, Valid
|
|||||||
}
|
}
|
||||||
|
|
||||||
ConfigEntryValidator entryValidator;
|
ConfigEntryValidator entryValidator;
|
||||||
var entrySpecificValidators = getEntrySpecificValidators(configEntry);
|
Collection<Middleware<ConfigEntryValidator>> entrySpecificValidators = getEntrySpecificValidators(configEntry);
|
||||||
if (entrySpecificValidators.isEmpty()) {
|
if (entrySpecificValidators.isEmpty()) {
|
||||||
entryValidator = entryValidatorMiddlewareContainer.process(baseValidator);
|
entryValidator = entryValidatorMiddlewareContainer.process(baseValidator);
|
||||||
} else {
|
} else {
|
||||||
@@ -166,7 +162,7 @@ public class ValidationExtensionImpl implements ReadWriteRelatedExtension, Valid
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Middleware<TweedEntryReader<?, ?>> entryReaderMiddleware() {
|
public @Nullable Middleware<TweedEntryReader<?, ?>> entryReaderMiddleware() {
|
||||||
return readerMiddleware;
|
return new EntryValidationReaderMiddleware();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package de.siphalor.tweed5.defaultextensions.validationfallback.api;
|
||||||
|
|
||||||
|
import de.siphalor.tweed5.core.api.extension.TweedExtension;
|
||||||
|
|
||||||
|
public interface ValidationFallbackExtension extends TweedExtension {
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package de.siphalor.tweed5.defaultextensions.validationfallback.api;
|
||||||
|
|
||||||
|
public interface ValidationFallbackValue {
|
||||||
|
Object validationFallbackValue();
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
package de.siphalor.tweed5.defaultextensions.validationfallback.impl;
|
||||||
|
|
||||||
|
import com.google.auto.service.AutoService;
|
||||||
|
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
|
||||||
|
import de.siphalor.tweed5.core.api.extension.TweedExtensionSetupContext;
|
||||||
|
import de.siphalor.tweed5.core.api.middleware.Middleware;
|
||||||
|
import de.siphalor.tweed5.defaultextensions.validation.api.ConfigEntryValidator;
|
||||||
|
import de.siphalor.tweed5.defaultextensions.validation.api.ValidationProvidingExtension;
|
||||||
|
import de.siphalor.tweed5.defaultextensions.validation.api.result.ValidationIssue;
|
||||||
|
import de.siphalor.tweed5.defaultextensions.validation.api.result.ValidationIssueLevel;
|
||||||
|
import de.siphalor.tweed5.defaultextensions.validation.api.result.ValidationResult;
|
||||||
|
import de.siphalor.tweed5.defaultextensions.validationfallback.api.ValidationFallbackExtension;
|
||||||
|
import de.siphalor.tweed5.defaultextensions.validationfallback.api.ValidationFallbackValue;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@AutoService(ValidationFallbackExtension.class)
|
||||||
|
public class ValidationFallbackExtensionImpl implements ValidationFallbackExtension, ValidationProvidingExtension {
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return "validation-fallback";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup(TweedExtensionSetupContext context) {
|
||||||
|
context.registerEntryExtensionData(ValidationFallbackValue.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Middleware<ConfigEntryValidator> validationMiddleware() {
|
||||||
|
return new ValidationFallbackMiddleware();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ValidationFallbackMiddleware implements Middleware<ConfigEntryValidator> {
|
||||||
|
@Override
|
||||||
|
public String id() {
|
||||||
|
return "validation-fallback";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> mustComeBefore() {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> mustComeAfter() {
|
||||||
|
return Collections.singleton("$default.end");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigEntryValidator process(ConfigEntryValidator inner) {
|
||||||
|
return new ConfigEntryValidator() {
|
||||||
|
@Override
|
||||||
|
public <T> ValidationResult<T> validate(ConfigEntry<T> configEntry, T value) {
|
||||||
|
ValidationResult<T> result = inner.validate(configEntry, value);
|
||||||
|
if (!result.hasError()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (!configEntry.extensionsData().isPatchworkPartSet(ValidationFallbackValue.class)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object fallbackValue = ((ValidationFallbackValue) configEntry.extensionsData()).validationFallbackValue();
|
||||||
|
if (fallbackValue != null) {
|
||||||
|
if (fallbackValue.getClass() == configEntry.valueClass()) {
|
||||||
|
//noinspection unchecked
|
||||||
|
fallbackValue = configEntry.deepCopy((T) fallbackValue);
|
||||||
|
} else {
|
||||||
|
ArrayList<ValidationIssue> issues = new ArrayList<>(result.issues());
|
||||||
|
issues.add(new ValidationIssue(
|
||||||
|
"Fallback value is not of correct class, expected " + configEntry.valueClass().getName() +
|
||||||
|
", but got " + fallbackValue.getClass().getName(),
|
||||||
|
ValidationIssueLevel.ERROR
|
||||||
|
));
|
||||||
|
return ValidationResult.withIssues(value, issues);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//noinspection unchecked
|
||||||
|
return ValidationResult.withIssues(
|
||||||
|
(T) fallbackValue,
|
||||||
|
result.issues().stream()
|
||||||
|
.map(issue -> new ValidationIssue(issue.message(), ValidationIssueLevel.WARN))
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull <T> String description(ConfigEntry<T> configEntry) {
|
||||||
|
if (!configEntry.extensionsData().isPatchworkPartSet(ValidationFallbackValue.class)) {
|
||||||
|
return inner.description(configEntry);
|
||||||
|
}
|
||||||
|
return inner.description(configEntry) +
|
||||||
|
"\n\nDefault/Fallback value: " +
|
||||||
|
((ValidationFallbackValue) configEntry.extensionsData()).validationFallbackValue();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
package de.siphalor.tweed5.defaultextensions.validationfallback.impl;
|
||||||
|
|
||||||
|
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
|
||||||
|
import de.siphalor.tweed5.core.api.extension.EntryExtensionsData;
|
||||||
|
import de.siphalor.tweed5.core.api.extension.RegisteredExtensionData;
|
||||||
|
import de.siphalor.tweed5.core.impl.DefaultConfigContainer;
|
||||||
|
import de.siphalor.tweed5.core.impl.entry.SimpleConfigEntryImpl;
|
||||||
|
import de.siphalor.tweed5.data.extension.api.EntryReaderWriterDefinition;
|
||||||
|
import de.siphalor.tweed5.data.extension.api.ReadWriteExtension;
|
||||||
|
import de.siphalor.tweed5.data.extension.api.TweedEntryReader;
|
||||||
|
import de.siphalor.tweed5.data.extension.api.TweedEntryWriter;
|
||||||
|
import de.siphalor.tweed5.data.extension.api.readwrite.TweedEntryReaderWriters;
|
||||||
|
import de.siphalor.tweed5.data.extension.impl.ReadWriteExtensionImpl;
|
||||||
|
import de.siphalor.tweed5.data.hjson.HjsonCommentType;
|
||||||
|
import de.siphalor.tweed5.data.hjson.HjsonLexer;
|
||||||
|
import de.siphalor.tweed5.data.hjson.HjsonReader;
|
||||||
|
import de.siphalor.tweed5.data.hjson.HjsonWriter;
|
||||||
|
import de.siphalor.tweed5.defaultextensions.comment.api.CommentExtension;
|
||||||
|
import de.siphalor.tweed5.defaultextensions.comment.impl.CommentExtensionImpl;
|
||||||
|
import de.siphalor.tweed5.defaultextensions.validation.api.ConfigEntryValidator;
|
||||||
|
import de.siphalor.tweed5.defaultextensions.validation.api.EntrySpecificValidation;
|
||||||
|
import de.siphalor.tweed5.defaultextensions.validation.api.ValidationExtension;
|
||||||
|
import de.siphalor.tweed5.defaultextensions.validation.api.result.ValidationIssue;
|
||||||
|
import de.siphalor.tweed5.defaultextensions.validation.api.result.ValidationIssueLevel;
|
||||||
|
import de.siphalor.tweed5.defaultextensions.validation.api.result.ValidationResult;
|
||||||
|
import de.siphalor.tweed5.defaultextensions.validation.api.validators.SimpleValidatorMiddleware;
|
||||||
|
import de.siphalor.tweed5.defaultextensions.validation.impl.ValidationExtensionImpl;
|
||||||
|
import de.siphalor.tweed5.defaultextensions.validationfallback.api.ValidationFallbackExtension;
|
||||||
|
import de.siphalor.tweed5.defaultextensions.validationfallback.api.ValidationFallbackValue;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
class ValidationFallbackExtensionImplTest {
|
||||||
|
private DefaultConfigContainer<Integer> configContainer;
|
||||||
|
private CommentExtension commentExtension;
|
||||||
|
private ValidationExtension validationExtension;
|
||||||
|
private ValidationFallbackExtension validationFallbackExtension;
|
||||||
|
private ReadWriteExtension readWriteExtension;
|
||||||
|
private SimpleConfigEntryImpl<Integer> intEntry;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
configContainer = new DefaultConfigContainer<>();
|
||||||
|
commentExtension = new CommentExtensionImpl();
|
||||||
|
configContainer.registerExtension(commentExtension);
|
||||||
|
validationExtension = new ValidationExtensionImpl();
|
||||||
|
configContainer.registerExtension(validationExtension);
|
||||||
|
validationFallbackExtension = new ValidationFallbackExtensionImpl();
|
||||||
|
configContainer.registerExtension(validationFallbackExtension);
|
||||||
|
readWriteExtension = new ReadWriteExtensionImpl();
|
||||||
|
configContainer.registerExtension(readWriteExtension);
|
||||||
|
|
||||||
|
configContainer.finishExtensionSetup();
|
||||||
|
|
||||||
|
intEntry = new SimpleConfigEntryImpl<>(Integer.class);
|
||||||
|
|
||||||
|
configContainer.attachAndSealTree(intEntry);
|
||||||
|
|
||||||
|
RegisteredExtensionData<EntryExtensionsData, EntrySpecificValidation> entrySpecificValidation = (RegisteredExtensionData<EntryExtensionsData, EntrySpecificValidation>) configContainer.entryDataExtensions().get(EntrySpecificValidation.class);
|
||||||
|
entrySpecificValidation.set(intEntry.extensionsData(), () -> Arrays.asList(
|
||||||
|
new SimpleValidatorMiddleware("non-null", new ConfigEntryValidator() {
|
||||||
|
@Override
|
||||||
|
public <T> ValidationResult<T> validate(ConfigEntry<T> configEntry, T value) {
|
||||||
|
if (value == null) {
|
||||||
|
return ValidationResult.withIssues(null, Collections.singleton(
|
||||||
|
new ValidationIssue("Value must not be null", ValidationIssueLevel.ERROR)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return ValidationResult.ok(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull <T> String description(ConfigEntry<T> configEntry) {
|
||||||
|
return "Must not be null.";
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new SimpleValidatorMiddleware("range", new ConfigEntryValidator() {
|
||||||
|
@Override
|
||||||
|
public <T> ValidationResult<T> validate(ConfigEntry<T> configEntry, T value) {
|
||||||
|
Integer intValue = (Integer) value;
|
||||||
|
if (intValue < 1) {
|
||||||
|
return ValidationResult.withIssues(value, Collections.singleton(new ValidationIssue("Must be greater or equal to 1", ValidationIssueLevel.ERROR)));
|
||||||
|
}
|
||||||
|
if (intValue > 6) {
|
||||||
|
return ValidationResult.withIssues(value, Collections.singleton(new ValidationIssue("Must be smaller or equal to 6", ValidationIssueLevel.ERROR)));
|
||||||
|
}
|
||||||
|
return ValidationResult.ok(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull <T> String description(ConfigEntry<T> configEntry) {
|
||||||
|
return "Must be between 1 and 6";
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
@Override
|
||||||
|
public Set<String> mustComeAfter() {
|
||||||
|
return Collections.singleton("non-null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
RegisteredExtensionData<EntryExtensionsData, ValidationFallbackValue> validationFallbackValue = (RegisteredExtensionData<EntryExtensionsData, ValidationFallbackValue>) configContainer.entryDataExtensions().get(ValidationFallbackValue.class);
|
||||||
|
validationFallbackValue.set(intEntry.extensionsData(), () -> 3);
|
||||||
|
|
||||||
|
RegisteredExtensionData<EntryExtensionsData, EntryReaderWriterDefinition> readerWriterData = (RegisteredExtensionData<EntryExtensionsData, EntryReaderWriterDefinition>) configContainer.entryDataExtensions().get(EntryReaderWriterDefinition.class);
|
||||||
|
readerWriterData.set(intEntry.extensionsData(), new EntryReaderWriterDefinition() {
|
||||||
|
@Override
|
||||||
|
public TweedEntryReader<?, ?> reader() {
|
||||||
|
return TweedEntryReaderWriters.nullableReaderWriter(TweedEntryReaderWriters.intReaderWriter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TweedEntryWriter<?, ?> writer() {
|
||||||
|
return TweedEntryReaderWriters.nullableReaderWriter(TweedEntryReaderWriters.intReaderWriter());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
configContainer.initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = {"0", "7", "123", "null"})
|
||||||
|
void fallbackTriggers(String input) {
|
||||||
|
Integer result = assertDoesNotThrow(() -> readWriteExtension.read(
|
||||||
|
new HjsonReader(new HjsonLexer(new StringReader(input))),
|
||||||
|
intEntry,
|
||||||
|
readWriteExtension.createReadWriteContextExtensionsData()
|
||||||
|
));
|
||||||
|
assertEquals(3, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void description() {
|
||||||
|
StringWriter stringWriter = new StringWriter();
|
||||||
|
assertDoesNotThrow(() -> readWriteExtension.write(
|
||||||
|
new HjsonWriter(stringWriter, new HjsonWriter.Options().multilineCommentType(HjsonCommentType.SLASHES)),
|
||||||
|
5,
|
||||||
|
intEntry,
|
||||||
|
readWriteExtension.createReadWriteContextExtensionsData()
|
||||||
|
));
|
||||||
|
|
||||||
|
assertEquals("// Must not be null.\n// Must be between 1 and 6\n// \n// Default/Fallback value: 3\n5\n", stringWriter.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,6 +43,10 @@ public class TweedEntryReaderWriters {
|
|||||||
return TweedEntryReaderWriterImpls.STRING_READER_WRITER;
|
return TweedEntryReaderWriterImpls.STRING_READER_WRITER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T, C extends ConfigEntry<T>> TweedEntryReaderWriter<T, C> nullableReaderWriter(TweedEntryReaderWriter<T, C> delegate) {
|
||||||
|
return new TweedEntryReaderWriterImpls.NullableReaderWriter<>(delegate);
|
||||||
|
}
|
||||||
|
|
||||||
public static <T, C extends Collection<T>> TweedEntryReaderWriter<C, CoherentCollectionConfigEntry<T, C>> coherentCollectionReaderWriter() {
|
public static <T, C extends Collection<T>> TweedEntryReaderWriter<C, CoherentCollectionConfigEntry<T, C>> coherentCollectionReaderWriter() {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return (TweedEntryReaderWriter<C, CoherentCollectionConfigEntry<T,C>>)(TweedEntryReaderWriter<?, ?>) TweedEntryReaderWriterImpls.COHERENT_COLLECTION_READER_WRITER;
|
return (TweedEntryReaderWriter<C, CoherentCollectionConfigEntry<T,C>>)(TweedEntryReaderWriter<?, ?>) TweedEntryReaderWriterImpls.COHERENT_COLLECTION_READER_WRITER;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import de.siphalor.tweed5.patchwork.api.Patchwork;
|
|||||||
import de.siphalor.tweed5.patchwork.api.PatchworkClassCreator;
|
import de.siphalor.tweed5.patchwork.api.PatchworkClassCreator;
|
||||||
import de.siphalor.tweed5.patchwork.impl.PatchworkClass;
|
import de.siphalor.tweed5.patchwork.impl.PatchworkClass;
|
||||||
import de.siphalor.tweed5.patchwork.impl.PatchworkClassGenerator;
|
import de.siphalor.tweed5.patchwork.impl.PatchworkClassGenerator;
|
||||||
|
import de.siphalor.tweed5.patchwork.impl.PatchworkClassPart;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
|
|
||||||
@@ -91,6 +92,10 @@ public class ReadWriteExtensionImpl implements ReadWriteExtension {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
readWriteContextExtensionsDataPatchwork = patchworkClassCreator.createClass(readWriteContextExtensionsDataClasses.keySet());
|
readWriteContextExtensionsDataPatchwork = patchworkClassCreator.createClass(readWriteContextExtensionsDataClasses.keySet());
|
||||||
|
for (PatchworkClassPart patchworkClassPart : readWriteContextExtensionsDataPatchwork.parts()) {
|
||||||
|
RegisteredExtensionDataImpl<ReadWriteContextExtensionsData, ?> registeredExtension = readWriteContextExtensionsDataClasses.get(patchworkClassPart.partInterface());
|
||||||
|
registeredExtension.setter = patchworkClassPart.fieldSetter();
|
||||||
|
}
|
||||||
} catch (PatchworkClassGenerator.GenerationException e) {
|
} catch (PatchworkClassGenerator.GenerationException e) {
|
||||||
throw new IllegalStateException("Failed to generate read write context extensions' data patchwork class", e);
|
throw new IllegalStateException("Failed to generate read write context extensions' data patchwork class", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,28 @@ public class TweedEntryReaderWriterImpls {
|
|||||||
|
|
||||||
public static final TweedEntryReaderWriter<Object, ConfigEntry<Object>> NOOP_READER_WRITER = new NoopReaderWriter();
|
public static final TweedEntryReaderWriter<Object, ConfigEntry<Object>> NOOP_READER_WRITER = new NoopReaderWriter();
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public static class NullableReaderWriter<T, C extends ConfigEntry<T>> implements TweedEntryReaderWriter<T, C> {
|
||||||
|
private final TweedEntryReaderWriter<T, C> delegate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T read(TweedDataReader reader, C entry, TweedReadContext context) throws TweedEntryReadException, TweedDataReadException {
|
||||||
|
if (reader.peekToken().isNull()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return delegate.read(reader, entry, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(TweedDataVisitor writer, T value, C entry, TweedWriteContext context) throws TweedEntryWriteException, TweedDataWriteException {
|
||||||
|
if (value == null) {
|
||||||
|
writer.visitNull();
|
||||||
|
} else {
|
||||||
|
delegate.write(writer, value, entry, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
private static class PrimitiveReaderWriter<T> implements TweedEntryReaderWriter<T, ConfigEntry<T>> {
|
private static class PrimitiveReaderWriter<T> implements TweedEntryReaderWriter<T, ConfigEntry<T>> {
|
||||||
private final Function<TweedDataToken, T> readerCall;
|
private final Function<TweedDataToken, T> readerCall;
|
||||||
|
|||||||
Reference in New Issue
Block a user