[core] Introduce arity for structured sub entries

This commit is contained in:
2025-10-28 20:53:23 +01:00
parent 370324668d
commit 0325dbf4e4
7 changed files with 69 additions and 19 deletions

View File

@@ -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;
}

View File

@@ -1,5 +1,6 @@
package de.siphalor.tweed5.core.api.entry; package de.siphalor.tweed5.core.api.entry;
import de.siphalor.tweed5.core.api.Arity;
import org.jspecify.annotations.Nullable; import org.jspecify.annotations.Nullable;
import java.util.Collection; import java.util.Collection;
@@ -14,6 +15,19 @@ public interface CollectionConfigEntry<E, T extends Collection<E>> extends Struc
return this; 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 @Override
default void visitInOrder(ConfigEntryValueVisitor visitor, @Nullable T value) { default void visitInOrder(ConfigEntryValueVisitor visitor, @Nullable T value) {
if (value == null) { if (value == null) {

View File

@@ -1,5 +1,7 @@
package de.siphalor.tweed5.core.api.entry; package de.siphalor.tweed5.core.api.entry;
import de.siphalor.tweed5.core.api.Arity;
import java.util.function.Consumer; import java.util.function.Consumer;
public interface CompoundConfigEntry<T> extends StructuredConfigEntry<T> { public interface CompoundConfigEntry<T> extends StructuredConfigEntry<T> {
@@ -13,4 +15,17 @@ public interface CompoundConfigEntry<T> extends StructuredConfigEntry<T> {
<V> V get(T compoundValue, String key); <V> V get(T compoundValue, String key);
T instantiateCompoundValue(); 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);
}
}
} }

View File

@@ -1,5 +1,7 @@
package de.siphalor.tweed5.core.api.entry; package de.siphalor.tweed5.core.api.entry;
import de.siphalor.tweed5.core.api.Arity;
public interface ConfigEntryVisitor { public interface ConfigEntryVisitor {
void visitEntry(ConfigEntry<?> entry); void visitEntry(ConfigEntry<?> entry);
@@ -8,11 +10,11 @@ public interface ConfigEntryVisitor {
return true; return true;
} }
default boolean enterStructuredSubEntry(String key) { default boolean enterStructuredSubEntry(String key, Arity arity) {
return true; return true;
} }
default void leaveStructuredSubEntry(String key) { default void leaveStructuredSubEntry(String key, Arity arity) {
} }
default void leaveStructuredEntry(ConfigEntry<?> entry) { default void leaveStructuredEntry(ConfigEntry<?> entry) {

View File

@@ -1,5 +1,6 @@
package de.siphalor.tweed5.core.api.entry; package de.siphalor.tweed5.core.api.entry;
import de.siphalor.tweed5.core.api.Arity;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -14,4 +15,17 @@ public interface NullableConfigEntry<T extends @Nullable Object> extends Structu
} }
ConfigEntry<T> nonNullEntry(); ConfigEntry<T> 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);
}
}
} }

View File

@@ -10,18 +10,5 @@ public interface StructuredConfigEntry<T> extends ConfigEntry<T> {
return this; 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<String, ConfigEntry<?>> subEntries(); Map<String, ConfigEntry<?>> subEntries();
} }

View File

@@ -1,5 +1,6 @@
package de.siphalor.tweed5.defaultextensions.pather.api; 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.ConfigEntry;
import de.siphalor.tweed5.core.api.entry.ConfigEntryVisitor; import de.siphalor.tweed5.core.api.entry.ConfigEntryVisitor;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@@ -20,8 +21,8 @@ public class PathTrackingConfigEntryVisitor implements ConfigEntryVisitor {
} }
@Override @Override
public boolean enterStructuredSubEntry(String key) { public boolean enterStructuredSubEntry(String key, Arity arity) {
boolean enter = delegate.enterStructuredSubEntry(key); boolean enter = delegate.enterStructuredSubEntry(key, arity);
if (enter) { if (enter) {
pathTracking.pushPathPart(key); pathTracking.pushPathPart(key);
} }
@@ -29,8 +30,8 @@ public class PathTrackingConfigEntryVisitor implements ConfigEntryVisitor {
} }
@Override @Override
public void leaveStructuredSubEntry(String key) { public void leaveStructuredSubEntry(String key, Arity arity) {
delegate.leaveStructuredSubEntry(key); delegate.leaveStructuredSubEntry(key, arity);
pathTracking.popPathPart(); pathTracking.popPathPart();
} }