From f22c359a1c9357d83d3ff641a9b0bbb1d89acd2f Mon Sep 17 00:00:00 2001 From: Siphalor Date: Sun, 24 May 2026 16:45:59 +0200 Subject: [PATCH] refactor(serde-ext, default-ext): Move path tracking into serde extension --- CHANGELOG.md | 2 + .../pather/api/PatherExtension.java | 3 +- .../pather/impl/PatherExtensionImpl.java | 117 +----------------- .../impl/ReadFallbackExtensionImpl.java | 3 +- .../impl/ValidationExtensionImpl.java | 23 +--- .../impl/ReadFallbackExtensionImplTest.java | 2 - .../serde/extension/api/TweedReadContext.java | 3 + .../extension/api/TweedWriteContext.java | 3 + .../serde/extension/api/path/EntryPath.java | 19 +++ .../readwrite/TweedEntryReaderWriters.java | 5 + .../impl/TweedReadWriteContextImpl.java | 33 ++++- .../impl/path/ReadWritePathTracking.java | 36 ++++++ .../impl/ReadWriteExtensionImplTest.java | 14 +-- 13 files changed, 119 insertions(+), 144 deletions(-) create mode 100644 tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/api/path/EntryPath.java create mode 100644 tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/impl/path/ReadWritePathTracking.java diff --git a/CHANGELOG.md b/CHANGELOG.md index db6b07e..9200bf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `core`: Fixed return type of `MutableStructuredConfigEntry#apply` to correctly be itself. - `minecraft-fabric-helper`: Fixed missing new line in error log message. +- `serde-extension`, `default-extensions`: Integrate path tracking into `ReadWriteExtension`, deprecate the existing + `PatherExtension` - `type-utls`: Fixed missing `@Nullable` annotation on `ActualType#getAnnotation`. - `weaver-pojo`: Fixed `StringMapPojoWeaver` weaving entries without `@StringMapWeaving` annotation. diff --git a/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/pather/api/PatherExtension.java b/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/pather/api/PatherExtension.java index 92edc19..095aa22 100644 --- a/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/pather/api/PatherExtension.java +++ b/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/pather/api/PatherExtension.java @@ -1,10 +1,11 @@ package de.siphalor.tweed5.defaultextensions.pather.api; import de.siphalor.tweed5.core.api.extension.TweedExtension; +import de.siphalor.tweed5.defaultextensions.pather.impl.PatherExtensionImpl; import de.siphalor.tweed5.serde.extension.api.TweedReadContext; import de.siphalor.tweed5.serde.extension.api.TweedWriteContext; -import de.siphalor.tweed5.defaultextensions.pather.impl.PatherExtensionImpl; +@Deprecated public interface PatherExtension extends TweedExtension { Class DEFAULT = PatherExtensionImpl.class; String EXTENSION_ID = "pather"; diff --git a/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/pather/impl/PatherExtensionImpl.java b/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/pather/impl/PatherExtensionImpl.java index 4ece752..a98e194 100644 --- a/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/pather/impl/PatherExtensionImpl.java +++ b/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/pather/impl/PatherExtensionImpl.java @@ -1,124 +1,17 @@ package de.siphalor.tweed5.defaultextensions.pather.impl; -import de.siphalor.tweed5.core.api.entry.ConfigEntry; -import de.siphalor.tweed5.core.api.middleware.Middleware; -import de.siphalor.tweed5.serde.extension.api.*; -import de.siphalor.tweed5.serde.extension.api.extension.ReadWriteExtensionSetupContext; -import de.siphalor.tweed5.serde.extension.api.extension.ReadWriteRelatedExtension; -import de.siphalor.tweed5.serde.extension.api.extension.ReaderMiddlewareContext; -import de.siphalor.tweed5.serde.extension.api.extension.WriterMiddlewareContext; -import de.siphalor.tweed5.serde_api.api.TweedDataReader; -import de.siphalor.tweed5.serde_api.api.TweedDataVisitor; -import de.siphalor.tweed5.defaultextensions.pather.api.PathTracking; -import de.siphalor.tweed5.defaultextensions.pather.api.PathTrackingDataReader; -import de.siphalor.tweed5.defaultextensions.pather.api.PathTrackingDataVisitor; import de.siphalor.tweed5.defaultextensions.pather.api.PatherExtension; -import de.siphalor.tweed5.patchwork.api.PatchworkPartAccess; -import lombok.val; -import org.jspecify.annotations.NonNull; -import org.jspecify.annotations.Nullable; - -public class PatherExtensionImpl implements PatherExtension, ReadWriteRelatedExtension { - private @Nullable PatchworkPartAccess rwContextPathTrackingAccess; - - @Override - public void setupReadWriteExtension(ReadWriteExtensionSetupContext context) { - rwContextPathTrackingAccess = context.registerReadWriteContextExtensionData(PathTracking.class); - context.registerReaderMiddleware(createEntryReaderMiddleware()); - context.registerWriterMiddleware(createEntryWriterMiddleware()); - } +import de.siphalor.tweed5.serde.extension.api.TweedReadContext; +import de.siphalor.tweed5.serde.extension.api.TweedWriteContext; +public class PatherExtensionImpl implements PatherExtension { @Override public String getPath(TweedReadContext context) { - assert rwContextPathTrackingAccess != null; - - PathTracking pathTracking = context.extensionsData().get(rwContextPathTrackingAccess); - if (pathTracking == null) { - throw new IllegalStateException("Path tracking is not active!"); - } - return pathTracking.currentPath(); + return context.currentEntryPath().toString(); } @Override public String getPath(TweedWriteContext context) { - assert rwContextPathTrackingAccess != null; - - PathTracking pathTracking = context.extensionsData().get(rwContextPathTrackingAccess); - if (pathTracking == null) { - throw new IllegalStateException("Path tracking is not active!"); - } - return pathTracking.currentPath(); - } - - private Middleware, ReaderMiddlewareContext> createEntryReaderMiddleware() { - return new Middleware, ReaderMiddlewareContext>() { - @Override - public String id() { - return EXTENSION_ID; - } - - @Override - public TweedEntryReader process(TweedEntryReader inner, ReaderMiddlewareContext context) { - assert rwContextPathTrackingAccess != null; - - //noinspection unchecked - val castedInner = (TweedEntryReader>) inner; - - return (TweedDataReader reader, ConfigEntry entry, TweedReadContext readContext) -> { - PathTracking pathTracking = readContext.extensionsData().get(rwContextPathTrackingAccess); - if (pathTracking != null) { - return castedInner.read(reader, entry, readContext); - } - - pathTracking = PathTracking.create(); - readContext.extensionsData().set(rwContextPathTrackingAccess, pathTracking); - return castedInner.read(new PathTrackingDataReader(reader, pathTracking), entry, readContext); - }; - } - }; - } - - private Middleware, WriterMiddlewareContext> createEntryWriterMiddleware() { - return new Middleware, WriterMiddlewareContext>() { - @Override - public String id() { - return EXTENSION_ID; - } - - @Override - public TweedEntryWriter process(TweedEntryWriter inner, WriterMiddlewareContext context) { - assert rwContextPathTrackingAccess != null; - - //noinspection unchecked - val castedInner = (TweedEntryWriter>) inner; - - return (TweedDataVisitor writer, Object value, ConfigEntry entry, TweedWriteContext writeContext) -> { - PathTracking pathTracking = writeContext.extensionsData().get(rwContextPathTrackingAccess); - if (pathTracking != null) { - castedInner.write(writer, value, entry, writeContext); - return; - } - - pathTracking = PathTracking.create(); - writeContext.extensionsData().set(rwContextPathTrackingAccess, pathTracking); - try { - castedInner.write(new PathTrackingDataVisitor(writer, pathTracking), value, entry, writeContext); - } catch (TweedEntryWriteException e) { - PathTracking exceptionPathTracking = - e.context().extensionsData().get(rwContextPathTrackingAccess); - if (exceptionPathTracking != null) { - throw new TweedEntryWriteException( - "Exception while writing entry at " - + exceptionPathTracking.currentPath() - + ": " + e.getMessage(), - e - ); - } else { - throw e; - } - } - }; - } - }; + return context.currentEntryPath().toString(); } } diff --git a/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/readfallback/impl/ReadFallbackExtensionImpl.java b/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/readfallback/impl/ReadFallbackExtensionImpl.java index 37c3b55..6a130b4 100644 --- a/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/readfallback/impl/ReadFallbackExtensionImpl.java +++ b/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/readfallback/impl/ReadFallbackExtensionImpl.java @@ -6,7 +6,6 @@ import de.siphalor.tweed5.core.api.middleware.Middleware; import de.siphalor.tweed5.serde.extension.api.TweedEntryReader; import de.siphalor.tweed5.serde.extension.api.extension.ReadWriteExtensionSetupContext; import de.siphalor.tweed5.serde.extension.api.extension.ReadWriteRelatedExtension; -import de.siphalor.tweed5.defaultextensions.pather.api.PatherExtension; import de.siphalor.tweed5.defaultextensions.presets.api.PresetsExtension; import de.siphalor.tweed5.defaultextensions.readfallback.api.ReadFallbackExtension; import de.siphalor.tweed5.defaultextensions.validation.api.ValidationExtension; @@ -39,7 +38,7 @@ public class ReadFallbackExtensionImpl implements ReadFallbackExtension, ReadWri @Override public Set mustComeBefore() { - return Collections.singleton(PatherExtension.EXTENSION_ID); + return Collections.emptySet(); } @Override diff --git a/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/validation/impl/ValidationExtensionImpl.java b/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/validation/impl/ValidationExtensionImpl.java index 32d5e18..0c0c8c5 100644 --- a/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/validation/impl/ValidationExtensionImpl.java +++ b/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/validation/impl/ValidationExtensionImpl.java @@ -14,7 +14,6 @@ import de.siphalor.tweed5.defaultextensions.comment.api.CommentProducer; import de.siphalor.tweed5.defaultextensions.comment.api.CommentProducerMiddlewareContext; import de.siphalor.tweed5.defaultextensions.pather.api.PathTracking; import de.siphalor.tweed5.defaultextensions.pather.api.PathTrackingConfigEntryValueVisitor; -import de.siphalor.tweed5.defaultextensions.pather.api.PatherExtension; import de.siphalor.tweed5.defaultextensions.pather.api.ValuePathTracking; import de.siphalor.tweed5.defaultextensions.validation.api.ConfigEntryValidator; import de.siphalor.tweed5.defaultextensions.validation.api.ValidationExtension; @@ -35,7 +34,6 @@ import de.siphalor.tweed5.serde.extension.api.read.result.TweedReadIssue; import de.siphalor.tweed5.serde.extension.api.read.result.TweedReadResult; import de.siphalor.tweed5.serde_api.api.TweedDataReader; import lombok.*; -import org.jetbrains.annotations.UnknownNullability; import org.jspecify.annotations.Nullable; import java.util.*; @@ -77,12 +75,10 @@ public class ValidationExtensionImpl implements ReadWriteRelatedExtension, Valid private final MiddlewareContainer entryValidatorMiddlewareContainer = new DefaultMiddlewareContainer<>(); private @Nullable PatchworkPartAccess readContextValidationIssuesAccess; - private @Nullable PatherExtension patherExtension; public ValidationExtensionImpl(ConfigContainer configContainer, TweedExtensionSetupContext context) { this.configContainer = configContainer; this.customEntryDataAccess = context.registerEntryExtensionData(CustomEntryData.class); - context.registerExtension(PatherExtension.class); } @Override @@ -95,9 +91,6 @@ public class ValidationExtensionImpl implements ReadWriteRelatedExtension, Valid } } entryValidatorMiddlewareContainer.seal(); - - patherExtension = configContainer.extension(PatherExtension.class) - .orElseThrow(() -> new IllegalStateException("Missing requested PatherExtension")); } @Override @@ -235,14 +228,9 @@ public class ValidationExtensionImpl implements ReadWriteRelatedExtension, Valid return EXTENSION_ID; } - @Override - public Set mustComeBefore() { - return Collections.singleton(PatherExtension.EXTENSION_ID); - } - @Override public TweedEntryReader process(TweedEntryReader inner, ReaderMiddlewareContext context) { - assert readContextValidationIssuesAccess != null && patherExtension != null; + assert readContextValidationIssuesAccess != null; //noinspection unchecked TweedEntryReader> castedInner = (TweedEntryReader>) inner; @@ -261,11 +249,10 @@ public class ValidationExtensionImpl implements ReadWriteRelatedExtension, Valid return TweedReadResult.ok(validationResult.value()); } - String path = patherExtension.getPath(readContext); - validationIssues.issuesByPath().put(path, new ValidationIssues.EntryIssues( - entry, - validationResult.issues() - )); + validationIssues.issuesByPath().put( + readContext.currentEntryPath().toString(), + new ValidationIssues.EntryIssues(entry, validationResult.issues()) + ); if (validationResult.hasError()) { return TweedReadResult.failed( mapValidationIssuesToReadIssues(validationResult.issues(), readContext) diff --git a/tweed5/default-extensions/src/test/java/de/siphalor/tweed5/defaultextensions/readfallback/impl/ReadFallbackExtensionImplTest.java b/tweed5/default-extensions/src/test/java/de/siphalor/tweed5/defaultextensions/readfallback/impl/ReadFallbackExtensionImplTest.java index bec8481..6a6622d 100644 --- a/tweed5/default-extensions/src/test/java/de/siphalor/tweed5/defaultextensions/readfallback/impl/ReadFallbackExtensionImplTest.java +++ b/tweed5/default-extensions/src/test/java/de/siphalor/tweed5/defaultextensions/readfallback/impl/ReadFallbackExtensionImplTest.java @@ -6,7 +6,6 @@ import de.siphalor.tweed5.core.api.entry.ConfigEntry; import de.siphalor.tweed5.core.impl.DefaultConfigContainer; import de.siphalor.tweed5.core.impl.entry.SimpleConfigEntryImpl; import de.siphalor.tweed5.core.impl.entry.StaticMapCompoundConfigEntryImpl; -import de.siphalor.tweed5.defaultextensions.pather.api.PatherExtension; import de.siphalor.tweed5.defaultextensions.presets.api.PresetsExtension; import de.siphalor.tweed5.defaultextensions.readfallback.api.ReadFallbackExtension; import de.siphalor.tweed5.serde.extension.api.ReadWriteExtension; @@ -77,7 +76,6 @@ class ReadFallbackExtensionImplTest { void nestedWithPather(LogsCaptor logsCaptor) { DefaultConfigContainer> configContainer = new DefaultConfigContainer<>(); configContainer.registerExtension(ReadWriteExtension.class); - configContainer.registerExtension(PatherExtension.class); configContainer.registerExtension(PresetsExtension.class); configContainer.registerExtension(ReadFallbackExtension.DEFAULT); configContainer.finishExtensionSetup(); diff --git a/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/api/TweedReadContext.java b/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/api/TweedReadContext.java index 3d252b7..e4c7b7d 100644 --- a/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/api/TweedReadContext.java +++ b/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/api/TweedReadContext.java @@ -3,6 +3,7 @@ package de.siphalor.tweed5.serde.extension.api; import de.siphalor.tweed5.core.api.entry.ConfigEntry; import de.siphalor.tweed5.core.api.entry.SubEntryKey; import de.siphalor.tweed5.patchwork.api.Patchwork; +import de.siphalor.tweed5.serde.extension.api.path.EntryPath; import de.siphalor.tweed5.serde.extension.api.read.result.TweedReadResult; import de.siphalor.tweed5.serde_api.api.TweedDataReader; import org.jspecify.annotations.Nullable; @@ -10,6 +11,8 @@ import org.jspecify.annotations.Nullable; public interface TweedReadContext { ReadWriteExtension readWriteExtension(); Patchwork extensionsData(); + EntryPath currentEntryPath(); + EntryPath currentValuePath(); > TweedReadResult readSubEntry( TweedDataReader reader, C entry, SubEntryKey key diff --git a/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/api/TweedWriteContext.java b/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/api/TweedWriteContext.java index be81833..34a331c 100644 --- a/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/api/TweedWriteContext.java +++ b/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/api/TweedWriteContext.java @@ -3,12 +3,15 @@ package de.siphalor.tweed5.serde.extension.api; import de.siphalor.tweed5.core.api.entry.ConfigEntry; import de.siphalor.tweed5.core.api.entry.SubEntryKey; import de.siphalor.tweed5.patchwork.api.Patchwork; +import de.siphalor.tweed5.serde.extension.api.path.EntryPath; import de.siphalor.tweed5.serde_api.api.TweedDataVisitor; import de.siphalor.tweed5.serde_api.api.TweedDataWriteException; import org.jspecify.annotations.Nullable; public interface TweedWriteContext { Patchwork extensionsData(); + EntryPath currentEntryPath(); + EntryPath currentValuePath(); > void writeSubEntry( TweedDataVisitor writer, C entry, SubEntryKey key, @Nullable T value diff --git a/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/api/path/EntryPath.java b/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/api/path/EntryPath.java new file mode 100644 index 0000000..7bb49d7 --- /dev/null +++ b/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/api/path/EntryPath.java @@ -0,0 +1,19 @@ +package de.siphalor.tweed5.serde.extension.api.path; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.jspecify.annotations.Nullable; + +import java.util.List; + +@RequiredArgsConstructor +public class EntryPath { + @Getter + private final List<@Nullable String> parts; + private final String string; + + @Override + public String toString() { + return string; + } +} diff --git a/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/api/readwrite/TweedEntryReaderWriters.java b/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/api/readwrite/TweedEntryReaderWriters.java index 9bf026c..13d1835 100644 --- a/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/api/readwrite/TweedEntryReaderWriters.java +++ b/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/api/readwrite/TweedEntryReaderWriters.java @@ -89,4 +89,9 @@ public class TweedEntryReaderWriters { //noinspection unchecked return (TweedEntryReaderWriter>) (TweedEntryReaderWriter) TweedEntryReaderWriterImpls.COMPOUND_READER_WRITER; } + + public static TweedEntryReaderWriter> noopReaderWriter() { + //noinspection unchecked + return (TweedEntryReaderWriter>) (TweedEntryReaderWriter) TweedEntryReaderWriterImpls.NOOP_READER_WRITER; + } } diff --git a/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/impl/TweedReadWriteContextImpl.java b/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/impl/TweedReadWriteContextImpl.java index bd01949..febea0a 100644 --- a/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/impl/TweedReadWriteContextImpl.java +++ b/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/impl/TweedReadWriteContextImpl.java @@ -3,8 +3,10 @@ package de.siphalor.tweed5.serde.extension.impl; import de.siphalor.tweed5.core.api.entry.ConfigEntry; import de.siphalor.tweed5.core.api.entry.SubEntryKey; import de.siphalor.tweed5.serde.extension.api.*; +import de.siphalor.tweed5.serde.extension.api.path.EntryPath; import de.siphalor.tweed5.serde.extension.api.read.result.TweedReadResult; import de.siphalor.tweed5.patchwork.api.Patchwork; +import de.siphalor.tweed5.serde.extension.impl.path.ReadWritePathTracking; import de.siphalor.tweed5.serde_api.api.TweedDataReader; import de.siphalor.tweed5.serde_api.api.TweedDataVisitor; import de.siphalor.tweed5.serde_api.api.TweedDataWriteException; @@ -19,17 +21,44 @@ class TweedReadWriteContextImpl implements TweedReadContext, TweedWriteContext { @Getter private final Patchwork extensionsData; + private final ReadWritePathTracking entryPathTracking = new ReadWritePathTracking(); + private final ReadWritePathTracking valuePathTracking = new ReadWritePathTracking(); + + @Override + public EntryPath currentEntryPath() { + return new EntryPath(entryPathTracking.currentPathParts(), entryPathTracking.currentPath()); + } + + @Override + public EntryPath currentValuePath() { + return new EntryPath(valuePathTracking.currentPathParts(), valuePathTracking.currentPath()); + } + @Override public > TweedReadResult readSubEntry( TweedDataReader reader, C entry, SubEntryKey key ) { - return readWriteExtension.getReaderChain(entry).read(reader, entry, this); + try { + entryPathTracking.push(key.entry()); + valuePathTracking.push(key.value()); + return readWriteExtension.getReaderChain(entry).read(reader, entry, this); + } finally { + entryPathTracking.pop(); + valuePathTracking.pop(); + } } @Override public > void writeSubEntry( TweedDataVisitor writer, C entry, SubEntryKey key, @Nullable T value ) throws TweedEntryWriteException, TweedDataWriteException { - readWriteExtension.getWriterChain(entry).write(writer, value, entry, this); + try { + entryPathTracking.push(key.entry()); + valuePathTracking.push(key.value()); + readWriteExtension.getWriterChain(entry).write(writer, value, entry, this); + } finally { + entryPathTracking.pop(); + valuePathTracking.pop(); + } } } diff --git a/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/impl/path/ReadWritePathTracking.java b/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/impl/path/ReadWritePathTracking.java new file mode 100644 index 0000000..c58352e --- /dev/null +++ b/tweed5/serde-extension/src/main/java/de/siphalor/tweed5/serde/extension/impl/path/ReadWritePathTracking.java @@ -0,0 +1,36 @@ +package de.siphalor.tweed5.serde.extension.impl.path; + +import org.jspecify.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class ReadWritePathTracking { + private final StringBuilder pathBuilder = new StringBuilder(256); + private final List<@Nullable String> pathParts = new ArrayList<>(50); + + public void push(@Nullable String part) { + pathParts.add(part); + if (part != null) { + pathBuilder.append(".").append(part); + } + } + + public void pop() { + if (!pathParts.isEmpty()) { + String poppedPart = pathParts.remove(pathParts.size() - 1); + if (poppedPart != null) { + pathBuilder.setLength(pathBuilder.length() - poppedPart.length() - 1); + } + } + } + + public String currentPath() { + return pathBuilder.toString(); + } + + public List<@Nullable String> currentPathParts() { + return Collections.unmodifiableList(new ArrayList<>(pathParts)); + } +} diff --git a/tweed5/serde-extension/src/test/java/de/siphalor/tweed5/serde/extension/impl/ReadWriteExtensionImplTest.java b/tweed5/serde-extension/src/test/java/de/siphalor/tweed5/serde/extension/impl/ReadWriteExtensionImplTest.java index a34e99d..cab27e7 100644 --- a/tweed5/serde-extension/src/test/java/de/siphalor/tweed5/serde/extension/impl/ReadWriteExtensionImplTest.java +++ b/tweed5/serde-extension/src/test/java/de/siphalor/tweed5/serde/extension/impl/ReadWriteExtensionImplTest.java @@ -3,30 +3,30 @@ package de.siphalor.tweed5.serde.extension.impl; import de.siphalor.tweed5.core.api.container.ConfigContainer; 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.ConfigEntryValueVisitor; -import de.siphalor.tweed5.core.api.entry.ConfigEntryVisitor; import de.siphalor.tweed5.core.api.entry.MutableStructuredConfigEntry; import de.siphalor.tweed5.core.api.entry.SimpleConfigEntry; import de.siphalor.tweed5.core.impl.DefaultConfigContainer; import de.siphalor.tweed5.core.impl.entry.CollectionConfigEntryImpl; import de.siphalor.tweed5.core.impl.entry.SimpleConfigEntryImpl; import de.siphalor.tweed5.core.impl.entry.StaticMapCompoundConfigEntryImpl; -import de.siphalor.tweed5.patchwork.api.Patchwork; import de.siphalor.tweed5.serde.extension.api.ReadWriteExtension; import de.siphalor.tweed5.serde.hjson.HjsonLexer; import de.siphalor.tweed5.serde.hjson.HjsonReader; import de.siphalor.tweed5.serde.hjson.HjsonWriter; import de.siphalor.tweed5.serde_api.api.TweedDataVisitor; -import org.jspecify.annotations.NonNull; -import org.jspecify.annotations.Nullable; +import de.siphalor.tweed5.testutils.generic.entry.TestMapConfigEntry; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.function.Function; import static de.siphalor.tweed5.serde.extension.api.ReadWriteExtension.entryReaderWriter;