refactor!(serde-extension): Replace reader/writer chain APIs with readSubEntry and writeSubEntry methods

This commit is contained in:
2026-04-12 21:06:46 +02:00
parent a413fab8d5
commit 2f4011c144
8 changed files with 62 additions and 31 deletions

View File

@@ -10,7 +10,7 @@ java-test = "21"
jetbrains-annotations = "26.0.1" jetbrains-annotations = "26.0.1"
jspecify = "1.0.0" jspecify = "1.0.0"
junit = "5.12.0" junit = "5.12.0"
lombok = "1.18.38" lombok = "1.18.44"
logback = "1.5.18" logback = "1.5.18"
mockito = "5.14.2" mockito = "5.14.2"
shadow = "9.3.0" shadow = "9.3.0"

View File

@@ -324,6 +324,14 @@ public class TweedCoatMappersImpl {
public Patchwork extensionsData() { public Patchwork extensionsData() {
return readExtData; return readExtData;
} }
@Override
public <T, C extends ConfigEntry<T>> TweedReadResult<T> readSubEntry(
TweedDataReader reader,
C entry
) {
return TweedReadResult.empty();
}
} }
); );
} }

View File

@@ -126,6 +126,4 @@ public interface ReadWriteExtension extends TweedExtension {
Patchwork contextExtensionsData Patchwork contextExtensionsData
) throws TweedEntryWriteException; ) throws TweedEntryWriteException;
<T, C extends ConfigEntry<T>> TweedEntryReader<T, C> getReaderChain(C entry);
<T, C extends ConfigEntry<T>> TweedEntryWriter<T, C> getWriterChain(C entry);
} }

View File

@@ -1,8 +1,16 @@
package de.siphalor.tweed5.serde.extension.api; package de.siphalor.tweed5.serde.extension.api;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.patchwork.api.Patchwork; import de.siphalor.tweed5.patchwork.api.Patchwork;
import de.siphalor.tweed5.serde.extension.api.read.result.TweedReadResult;
import de.siphalor.tweed5.serde_api.api.TweedDataReader;
import org.jspecify.annotations.Nullable;
public interface TweedReadContext { public interface TweedReadContext {
ReadWriteExtension readWriteExtension(); ReadWriteExtension readWriteExtension();
Patchwork extensionsData(); Patchwork extensionsData();
<T extends @Nullable Object, C extends ConfigEntry<T>> TweedReadResult<T> readSubEntry(
TweedDataReader reader, C entry
);
} }

View File

@@ -1,8 +1,15 @@
package de.siphalor.tweed5.serde.extension.api; package de.siphalor.tweed5.serde.extension.api;
import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.patchwork.api.Patchwork; import de.siphalor.tweed5.patchwork.api.Patchwork;
import de.siphalor.tweed5.serde_api.api.TweedDataVisitor;
import de.siphalor.tweed5.serde_api.api.TweedDataWriteException;
import org.jspecify.annotations.Nullable;
public interface TweedWriteContext { public interface TweedWriteContext {
ReadWriteExtension readWriteExtension();
Patchwork extensionsData(); Patchwork extensionsData();
<T extends @Nullable Object, C extends ConfigEntry<T>> void writeSubEntry(
TweedDataVisitor writer, @Nullable T value, C entry
) throws TweedEntryWriteException, TweedDataWriteException;
} }

View File

@@ -179,14 +179,12 @@ public class ReadWriteExtensionImpl implements ReadWriteExtension {
private TweedEntryWriter<?, ?> writerChain; private TweedEntryWriter<?, ?> writerChain;
} }
@Override <T, C extends ConfigEntry<T>> TweedEntryReader<T, C> getReaderChain(C entry) {
public <T, C extends ConfigEntry<T>> TweedEntryReader<T, C> getReaderChain(C entry) {
//noinspection unchecked //noinspection unchecked
return (TweedEntryReader<T, C>) entry.extensionsData().get(customEntryDataAccess).readerChain(); return (TweedEntryReader<T, C>) entry.extensionsData().get(customEntryDataAccess).readerChain();
} }
@Override <T, C extends ConfigEntry<T>> TweedEntryWriter<T, C> getWriterChain(C entry) {
public <T, C extends ConfigEntry<T>> TweedEntryWriter<T, C> getWriterChain(C entry) {
//noinspection unchecked //noinspection unchecked
return (TweedEntryWriter<T, C>) entry.extensionsData().get(customEntryDataAccess).writerChain(); return (TweedEntryWriter<T, C>) entry.extensionsData().get(customEntryDataAccess).writerChain();
} }

View File

@@ -13,7 +13,6 @@ import de.siphalor.tweed5.serde_api.api.*;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.val;
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
import org.jspecify.annotations.Nullable; import org.jspecify.annotations.Nullable;
@@ -51,8 +50,7 @@ public class TweedEntryReaderWriterImpls {
return TweedReadResult.failed(TweedReadIssue.error(e, context)); return TweedReadResult.failed(TweedReadIssue.error(e, context));
} }
TweedEntryReader<T, ConfigEntry<T>> nonNullReader = context.readWriteExtension().getReaderChain(entry.nonNullEntry()); return context.readSubEntry(reader, entry.nonNullEntry());
return nonNullReader.read(reader, entry.nonNullEntry(), context);
} }
@Override @Override
@@ -65,8 +63,7 @@ public class TweedEntryReaderWriterImpls {
if (value == null) { if (value == null) {
writer.visitNull(); writer.visitNull();
} else { } else {
TweedEntryWriter<T, ConfigEntry<T>> nonNullWriter = context.readWriteExtension().getWriterChain(entry.nonNullEntry()); context.writeSubEntry(writer, value, entry.nonNullEntry());
nonNullWriter.write(writer, value, entry.nonNullEntry(), context);
} }
} }
} }
@@ -161,8 +158,6 @@ public class TweedEntryReaderWriterImpls {
} }
ConfigEntry<T> elementEntry = entry.elementEntry(); ConfigEntry<T> elementEntry = entry.elementEntry();
TweedEntryReader<T, ConfigEntry<T>> elementReader = context.readWriteExtension().getReaderChain(elementEntry);
List<T> list = new ArrayList<>(20); List<T> list = new ArrayList<>(20);
List<TweedReadIssue> issues = new ArrayList<>(); List<TweedReadIssue> issues = new ArrayList<>();
while (true) { while (true) {
@@ -172,7 +167,7 @@ public class TweedEntryReaderWriterImpls {
reader.readToken(); reader.readToken();
break; break;
} else if (token.isListValue()) { } else if (token.isListValue()) {
TweedReadResult<T> elementResult = elementReader.read(reader, elementEntry, context); TweedReadResult<T> elementResult = context.readSubEntry(reader, elementEntry);
issues.addAll(Arrays.asList(elementResult.issues())); issues.addAll(Arrays.asList(elementResult.issues()));
if (elementResult.isFailed() || elementResult.isError()) { if (elementResult.isFailed() || elementResult.isError()) {
return TweedReadResult.failed(issues.toArray(new TweedReadIssue[0])); return TweedReadResult.failed(issues.toArray(new TweedReadIssue[0]));
@@ -207,11 +202,10 @@ public class TweedEntryReaderWriterImpls {
} }
ConfigEntry<T> elementEntry = entry.elementEntry(); ConfigEntry<T> elementEntry = entry.elementEntry();
TweedEntryWriter<T, ConfigEntry<T>> elementWriter = context.readWriteExtension().getWriterChain(elementEntry);
writer.visitListStart(); writer.visitListStart();
for (T element : value) { for (T element : value) {
elementWriter.write(writer, element, elementEntry, context); context.writeSubEntry(writer, element, elementEntry);
} }
writer.visitListEnd(); writer.visitListEnd();
} }
@@ -242,8 +236,7 @@ public class TweedEntryReaderWriterImpls {
} }
continue; continue;
} }
val subEntryReaderChain = context.readWriteExtension().getReaderChain(subEntry); TweedReadResult<Object> subEntryResult = context.readSubEntry(reader, subEntry);
TweedReadResult<Object> subEntryResult = subEntryReaderChain.read(reader, subEntry, context);
issues.addAll(Arrays.asList(subEntryResult.issues())); issues.addAll(Arrays.asList(subEntryResult.issues()));
if (subEntryResult.isFailed() || subEntryResult.isError()) { if (subEntryResult.isFailed() || subEntryResult.isError()) {
return TweedReadResult.failed(issues.toArray(new TweedReadIssue[0])); return TweedReadResult.failed(issues.toArray(new TweedReadIssue[0]));
@@ -281,10 +274,8 @@ public class TweedEntryReaderWriterImpls {
String key = e.getKey(); String key = e.getKey();
ConfigEntry<Object> subEntry = e.getValue(); ConfigEntry<Object> subEntry = e.getValue();
TweedEntryWriter<Object, ConfigEntry<Object>> subEntryWriterChain = context.readWriteExtension().getWriterChain(subEntry);
writer.visitMapEntryKey(key); writer.visitMapEntryKey(key);
subEntryWriterChain.write(writer, entry.get(value, key), subEntry, context); context.writeSubEntry(writer, entry.get(value, key), subEntry);
} }
writer.visitMapEnd(); writer.visitMapEnd();

View File

@@ -1,13 +1,34 @@
package de.siphalor.tweed5.serde.extension.impl; package de.siphalor.tweed5.serde.extension.impl;
import de.siphalor.tweed5.serde.extension.api.ReadWriteExtension; import de.siphalor.tweed5.core.api.entry.ConfigEntry;
import de.siphalor.tweed5.serde.extension.api.TweedReadContext; import de.siphalor.tweed5.serde.extension.api.*;
import de.siphalor.tweed5.serde.extension.api.TweedWriteContext; import de.siphalor.tweed5.serde.extension.api.read.result.TweedReadResult;
import de.siphalor.tweed5.patchwork.api.Patchwork; import de.siphalor.tweed5.patchwork.api.Patchwork;
import lombok.Value; import de.siphalor.tweed5.serde_api.api.TweedDataReader;
import de.siphalor.tweed5.serde_api.api.TweedDataVisitor;
import de.siphalor.tweed5.serde_api.api.TweedDataWriteException;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.jspecify.annotations.Nullable;
@Value @RequiredArgsConstructor
public class TweedReadWriteContextImpl implements TweedReadContext, TweedWriteContext { class TweedReadWriteContextImpl implements TweedReadContext, TweedWriteContext {
ReadWriteExtension readWriteExtension; @Getter
Patchwork extensionsData; private final ReadWriteExtensionImpl readWriteExtension;
@Getter
private final Patchwork extensionsData;
@Override
public <T extends @Nullable Object, C extends ConfigEntry<T>> TweedReadResult<T> readSubEntry(
TweedDataReader reader, C entry
) {
return readWriteExtension.getReaderChain(entry).read(reader, entry, this);
}
@Override
public <T extends @Nullable Object, C extends ConfigEntry<T>> void writeSubEntry(
TweedDataVisitor writer, @Nullable T value, C entry
) throws TweedEntryWriteException, TweedDataWriteException {
readWriteExtension.getWriterChain(entry).write(writer, value, entry, this);
}
} }