diff --git a/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/Arity.java b/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/Arity.java new file mode 100644 index 0000000..ff3f095 --- /dev/null +++ b/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/Arity.java @@ -0,0 +1,17 @@ +package de.siphalor.tweed5.core.api; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Getter +public enum Arity { + SINGLE(1, 1), + OPTIONAL(0, 1), + MULTIPLE(1, Integer.MAX_VALUE), + ANY(0, Integer.MAX_VALUE), + ; + + private final int min; + private final int max; +} diff --git a/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/CollectionConfigEntry.java b/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/CollectionConfigEntry.java index 4d63e4f..b68f2fc 100644 --- a/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/CollectionConfigEntry.java +++ b/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/CollectionConfigEntry.java @@ -1,5 +1,6 @@ package de.siphalor.tweed5.core.api.entry; +import de.siphalor.tweed5.core.api.Arity; import org.jspecify.annotations.Nullable; import java.util.Collection; @@ -14,6 +15,19 @@ public interface CollectionConfigEntry> extends Struc return this; } + @Override + default void visitInOrder(ConfigEntryVisitor visitor) { + if (visitor.enterStructuredEntry(this)) { + subEntries().forEach((key, entry) -> { + if (visitor.enterStructuredSubEntry(key, Arity.ANY)) { + entry.visitInOrder(visitor); + visitor.leaveStructuredSubEntry(key, Arity.ANY); + } + }); + visitor.leaveStructuredEntry(this); + } + } + @Override default void visitInOrder(ConfigEntryValueVisitor visitor, @Nullable T value) { if (value == null) { diff --git a/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/CompoundConfigEntry.java b/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/CompoundConfigEntry.java index d73ea58..f7e7bdd 100644 --- a/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/CompoundConfigEntry.java +++ b/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/CompoundConfigEntry.java @@ -1,5 +1,7 @@ package de.siphalor.tweed5.core.api.entry; +import de.siphalor.tweed5.core.api.Arity; + import java.util.function.Consumer; public interface CompoundConfigEntry extends StructuredConfigEntry { @@ -13,4 +15,17 @@ public interface CompoundConfigEntry extends StructuredConfigEntry { V get(T compoundValue, String key); T instantiateCompoundValue(); + + @Override + default void visitInOrder(ConfigEntryVisitor visitor) { + if (visitor.enterStructuredEntry(this)) { + subEntries().forEach((key, entry) -> { + if (visitor.enterStructuredSubEntry(key, Arity.SINGLE)) { + entry.visitInOrder(visitor); + visitor.leaveStructuredSubEntry(key, Arity.SINGLE); + } + }); + visitor.leaveStructuredEntry(this); + } + } } diff --git a/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/ConfigEntryVisitor.java b/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/ConfigEntryVisitor.java index 7a58d06..1a4441c 100644 --- a/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/ConfigEntryVisitor.java +++ b/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/ConfigEntryVisitor.java @@ -1,5 +1,7 @@ package de.siphalor.tweed5.core.api.entry; +import de.siphalor.tweed5.core.api.Arity; + public interface ConfigEntryVisitor { void visitEntry(ConfigEntry entry); @@ -8,11 +10,11 @@ public interface ConfigEntryVisitor { return true; } - default boolean enterStructuredSubEntry(String key) { + default boolean enterStructuredSubEntry(String key, Arity arity) { return true; } - default void leaveStructuredSubEntry(String key) { + default void leaveStructuredSubEntry(String key, Arity arity) { } default void leaveStructuredEntry(ConfigEntry entry) { diff --git a/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/NullableConfigEntry.java b/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/NullableConfigEntry.java index dbe88c6..aaf6708 100644 --- a/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/NullableConfigEntry.java +++ b/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/NullableConfigEntry.java @@ -1,5 +1,6 @@ package de.siphalor.tweed5.core.api.entry; +import de.siphalor.tweed5.core.api.Arity; import org.jetbrains.annotations.Nullable; import java.util.function.Consumer; @@ -14,4 +15,17 @@ public interface NullableConfigEntry extends Structu } ConfigEntry nonNullEntry(); + + @Override + default void visitInOrder(ConfigEntryVisitor visitor) { + if (visitor.enterStructuredEntry(this)) { + subEntries().forEach((key, entry) -> { + if (visitor.enterStructuredSubEntry(key, Arity.OPTIONAL)) { + entry.visitInOrder(visitor); + visitor.leaveStructuredSubEntry(key, Arity.OPTIONAL); + } + }); + visitor.leaveStructuredEntry(this); + } + } } diff --git a/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/StructuredConfigEntry.java b/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/StructuredConfigEntry.java index 9d66aa4..59e78e6 100644 --- a/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/StructuredConfigEntry.java +++ b/tweed5/core/src/main/java/de/siphalor/tweed5/core/api/entry/StructuredConfigEntry.java @@ -10,18 +10,5 @@ public interface StructuredConfigEntry extends ConfigEntry { return this; } - @Override - default void visitInOrder(ConfigEntryVisitor visitor) { - if (visitor.enterStructuredEntry(this)) { - subEntries().forEach((key, entry) -> { - if (visitor.enterStructuredSubEntry(key)) { - entry.visitInOrder(visitor); - visitor.leaveStructuredSubEntry(key); - } - }); - visitor.leaveStructuredEntry(this); - } - } - Map> subEntries(); } diff --git a/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/pather/api/PathTrackingConfigEntryVisitor.java b/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/pather/api/PathTrackingConfigEntryVisitor.java index 126a3c8..ddc2315 100644 --- a/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/pather/api/PathTrackingConfigEntryVisitor.java +++ b/tweed5/default-extensions/src/main/java/de/siphalor/tweed5/defaultextensions/pather/api/PathTrackingConfigEntryVisitor.java @@ -1,5 +1,6 @@ package de.siphalor.tweed5.defaultextensions.pather.api; +import de.siphalor.tweed5.core.api.Arity; import de.siphalor.tweed5.core.api.entry.ConfigEntry; import de.siphalor.tweed5.core.api.entry.ConfigEntryVisitor; import lombok.RequiredArgsConstructor; @@ -20,8 +21,8 @@ public class PathTrackingConfigEntryVisitor implements ConfigEntryVisitor { } @Override - public boolean enterStructuredSubEntry(String key) { - boolean enter = delegate.enterStructuredSubEntry(key); + public boolean enterStructuredSubEntry(String key, Arity arity) { + boolean enter = delegate.enterStructuredSubEntry(key, arity); if (enter) { pathTracking.pushPathPart(key); } @@ -29,8 +30,8 @@ public class PathTrackingConfigEntryVisitor implements ConfigEntryVisitor { } @Override - public void leaveStructuredSubEntry(String key) { - delegate.leaveStructuredSubEntry(key); + public void leaveStructuredSubEntry(String key, Arity arity) { + delegate.leaveStructuredSubEntry(key, arity); pathTracking.popPathPart(); }