[core, weaver-pojo] Introduce NullableConfigEntry and pseudo entries during weaving

This commit is contained in:
2025-10-28 19:15:29 +01:00
parent ffbecb9158
commit 370324668d
21 changed files with 418 additions and 90 deletions

View File

@@ -3,12 +3,14 @@ package de.siphalor.tweed5.data.extension.api.readwrite;
import de.siphalor.tweed5.core.api.entry.CollectionConfigEntry;
import de.siphalor.tweed5.core.api.entry.CompoundConfigEntry;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.core.api.entry.NullableConfigEntry;
import de.siphalor.tweed5.data.extension.api.TweedEntryReader;
import de.siphalor.tweed5.data.extension.api.TweedEntryWriter;
import de.siphalor.tweed5.data.extension.impl.TweedEntryReaderWriterImpls;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import java.util.Collection;
@@ -51,12 +53,25 @@ public class TweedEntryReaderWriters {
return (TweedEntryReaderWriter<T, @NonNull ConfigEntry<T>>)(TweedEntryReaderWriter) TweedEntryReaderWriterImpls.ENUM_READER_WRITER;
}
public static <T, C extends ConfigEntry<T>> TweedEntryReader<T, C> nullableReader(TweedEntryReader<T, C> delegate) {
return new TweedEntryReaderWriterImpls.NullableReader<>(delegate);
public static <T extends @Nullable Object> TweedEntryReaderWriter<T, NullableConfigEntry<T>> nullableReaderWriter() {
//noinspection unchecked
return (TweedEntryReaderWriter<T, @NonNull NullableConfigEntry<T>>) (TweedEntryReaderWriter<?, ?>) TweedEntryReaderWriterImpls.NULLABLE_READER_WRITER;
}
/**
* @deprecated You probably want to use {@link #nullableReaderWriter()} instead.
*/
@Deprecated
public static <T, C extends ConfigEntry<T>> TweedEntryReader<T, C> nullableReader(TweedEntryReader<T, C> delegate) {
return new TweedEntryReaderWriterImpls.FixedNullableReader<>(delegate);
}
/**
* @deprecated You probably want to use {@link #nullableReaderWriter()} instead.
*/
@Deprecated
public static <T, C extends ConfigEntry<T>> TweedEntryWriter<T, C> nullableWriter(TweedEntryWriter<T, C> delegate) {
return new TweedEntryReaderWriterImpls.NullableWriter<>(delegate);
return new TweedEntryReaderWriterImpls.FixedNullableWriter<>(delegate);
}
public static <T, C extends Collection<T>> TweedEntryReaderWriter<C, CollectionConfigEntry<T, C>> collectionReaderWriter() {

View File

@@ -4,6 +4,10 @@ import com.google.auto.service.AutoService;
import de.siphalor.tweed5.data.extension.api.TweedEntryReader;
import de.siphalor.tweed5.data.extension.api.TweedEntryWriter;
import de.siphalor.tweed5.data.extension.api.TweedReaderWriterProvider;
import de.siphalor.tweed5.data.extension.api.readwrite.TweedEntryReaderWriters;
import lombok.RequiredArgsConstructor;
import java.util.function.Function;
import static de.siphalor.tweed5.data.extension.api.readwrite.TweedEntryReaderWriters.*;
@@ -39,22 +43,32 @@ public class DefaultTweedEntryReaderWriterImplsProvider implements TweedReaderWr
context.registerWriterFactory("tweed5.string", new StaticReaderWriterFactory<>(stringReaderWriter()));
context.registerReaderFactory("tweed5.enum", new StaticReaderWriterFactory<>(enumReaderWriter()));
context.registerWriterFactory("tweed5.enum", new StaticReaderWriterFactory<>(enumReaderWriter()));
context.registerReaderFactory("tweed5.nullable", new NullableReaderWriterFactory<>(
TweedEntryReaderWriters::nullableReader
));
context.registerWriterFactory("tweed5.nullable", new NullableReaderWriterFactory<>(
TweedEntryReaderWriters::nullableWriter
));
context.registerReaderFactory("tweed5.collection", new StaticReaderWriterFactory<>(collectionReaderWriter()));
context.registerWriterFactory("tweed5.collection", new StaticReaderWriterFactory<>(collectionReaderWriter()));
context.registerReaderFactory("tweed5.compound", new StaticReaderWriterFactory<>(compoundReaderWriter()));
context.registerWriterFactory("tweed5.compound", new StaticReaderWriterFactory<>(compoundReaderWriter()));
}
context.registerReaderFactory("tweed5.nullable", delegateReaders -> {
if (delegateReaders.length != 1) {
throw new IllegalArgumentException("Nullable reader requires a single delegate argument, got " + delegateReaders.length);
@RequiredArgsConstructor
private static class NullableReaderWriterFactory<T> implements ReaderWriterFactory<T> {
private final Function<T, T> delegateBasedFactory;
@Override
public T create(T... delegateReaderWriters) {
if (delegateReaderWriters.length == 0) {
//noinspection unchecked
return (T) TweedEntryReaderWriters.nullableReaderWriter();
} else if (delegateReaderWriters.length == 1) {
return delegateBasedFactory.apply(delegateReaderWriters[0]);
} else {
throw new IllegalArgumentException("Nullable readers and writers may have only one or zero delegates");
}
return nullableReader(delegateReaders[0]);
});
context.registerWriterFactory("tweed5.nullable", delegateWriters -> {
if (delegateWriters.length != 1) {
throw new IllegalArgumentException("Nullable writer requires a single delegate argument, got " + delegateWriters.length);
}
return nullableWriter(delegateWriters[0]);
});
}
}
}

View File

@@ -3,6 +3,7 @@ package de.siphalor.tweed5.data.extension.impl;
import de.siphalor.tweed5.core.api.entry.CollectionConfigEntry;
import de.siphalor.tweed5.core.api.entry.CompoundConfigEntry;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.core.api.entry.NullableConfigEntry;
import de.siphalor.tweed5.data.extension.api.*;
import de.siphalor.tweed5.data.extension.api.readwrite.TweedEntryReaderWriter;
import de.siphalor.tweed5.dataapi.api.*;
@@ -28,13 +29,48 @@ public class TweedEntryReaderWriterImpls {
public static final TweedEntryReaderWriter<String, ConfigEntry<String>> STRING_READER_WRITER = new PrimitiveReaderWriter<>(TweedDataToken::readAsString, TweedDataVisitor::visitString);
public static final TweedEntryReaderWriter<Enum<?>, ConfigEntry<Enum<?>>> ENUM_READER_WRITER = new EnumReaderWriter<>();
public static final TweedEntryReaderWriter<Object, NullableConfigEntry<Object>> NULLABLE_READER_WRITER = new NullableReaderWriter<>();
public static final TweedEntryReaderWriter<Collection<Object>, CollectionConfigEntry<Object, Collection<Object>>> COLLECTION_READER_WRITER = new CollectionReaderWriter<>();
public static final TweedEntryReaderWriter<Object, CompoundConfigEntry<Object>> COMPOUND_READER_WRITER = new CompoundReaderWriter<>();
public static final TweedEntryReaderWriter<Object, ConfigEntry<Object>> NOOP_READER_WRITER = new NoopReaderWriter();
public static class NullableReaderWriter<T extends @Nullable Object> implements TweedEntryReaderWriter<T, NullableConfigEntry<T>> {
@Override
public T read(TweedDataReader reader, NullableConfigEntry<T> entry, TweedReadContext context)
throws TweedEntryReadException {
try {
if (reader.peekToken().isNull()) {
reader.readToken();
return null;
}
} catch (TweedDataReadException e) {
throw new TweedEntryReadException(e, context);
}
TweedEntryReader<T, ConfigEntry<T>> nonNullReader = context.readWriteExtension().getReaderChain(entry.nonNullEntry());
return nonNullReader.read(reader, entry.nonNullEntry(), context);
}
@Override
public void write(
TweedDataVisitor writer,
@Nullable T value,
NullableConfigEntry<T> entry,
TweedWriteContext context
) throws TweedEntryWriteException, TweedDataWriteException {
if (value == null) {
writer.visitNull();
} else {
TweedEntryWriter<T, ConfigEntry<T>> nonNullWriter = context.readWriteExtension().getWriterChain(entry.nonNullEntry());
nonNullWriter.write(writer, value, entry.nonNullEntry(), context);
}
}
}
@Deprecated
@RequiredArgsConstructor
public static class NullableReader<T extends @Nullable Object, C extends ConfigEntry<T>> implements TweedEntryReader<T, C> {
public static class FixedNullableReader<T extends @Nullable Object, C extends ConfigEntry<T>> implements TweedEntryReader<T, C> {
private final TweedEntryReader<T, C> delegate;
@Override
@@ -51,8 +87,9 @@ public class TweedEntryReaderWriterImpls {
}
}
@Deprecated
@RequiredArgsConstructor
public static class NullableWriter<T extends @Nullable Object, C extends ConfigEntry<T>> implements TweedEntryWriter<T, C> {
public static class FixedNullableWriter<T extends @Nullable Object, C extends ConfigEntry<T>> implements TweedEntryWriter<T, C> {
private final TweedEntryWriter<T, C> delegate;
@Override