diff --git a/buildSrc/src/main/groovy/ethylene.library-conventions.gradle b/buildSrc/src/main/groovy/ethylene.library-conventions.gradle index 6aaea4d..8d423ac 100644 --- a/buildSrc/src/main/groovy/ethylene.library-conventions.gradle +++ b/buildSrc/src/main/groovy/ethylene.library-conventions.gradle @@ -6,7 +6,7 @@ plugins { } group 'com.github.steanky' -version '0.25.0' +version '0.26.0' publishing { publications { diff --git a/ethylene-core/src/main/java/com/github/steanky/ethylene/core/ConfigElement.java b/ethylene-core/src/main/java/com/github/steanky/ethylene/core/ConfigElement.java index c79bb63..1eb316a 100644 --- a/ethylene-core/src/main/java/com/github/steanky/ethylene/core/ConfigElement.java +++ b/ethylene-core/src/main/java/com/github/steanky/ethylene/core/ConfigElement.java @@ -11,6 +11,7 @@ import java.io.IOException; import java.util.List; import java.util.Objects; +import java.util.function.BooleanSupplier; import java.util.function.Supplier; import com.github.steanky.ethylene.core.processor.ConfigProcessor; @@ -236,6 +237,388 @@ else if (current.isList()) { return Objects.requireNonNullElse(at(path), defaultElement); } + /** + * Equivalent to {@link ConfigElement#at(ConfigPath)}, but returns {@code defaultValue} iff the element at the path + * does not exist or is not a container. + * + * @param path the path to search along + * @param defaultValue the default value + * @return the object at the path, else the default value + */ + default @NotNull ConfigContainer containerAtOrDefault(@NotNull ConfigPath path, @NotNull ConfigContainer defaultValue) { + Objects.requireNonNull(defaultValue); + + ConfigElement element = at(path); + if (element == null || !element.isContainer()) { + return defaultValue; + } + + return element.asContainer(); + } + + /** + * Equivalent to {@link ConfigElement#at(String)}, but returns {@code defaultValue} iff the element at the path + * does not exist or is not a container. + * + * @param path the path to search along + * @param defaultValue the default value + * @return the object at the path, else the default value + */ + default @NotNull ConfigContainer containerAtOrDefault(@NotNull String path, @NotNull ConfigContainer defaultValue) { + return containerAtOrDefault(ConfigPath.of(path), defaultValue); + } + + /** + * Equivalent to {@link ConfigElement#at(ConfigPath)}, but calls {@code defaultSupplier} to compute a default value + * iff the element at the path does not exist or is not a container. + * + * @param path the path to search along + * @param defaultSupplier the default value supplier, which must return a non-null value + * @return the object at the path, else the computed default value + */ + default @NotNull ConfigContainer containerAtOrDefault(@NotNull ConfigPath path, + @NotNull Supplier defaultSupplier) { + Objects.requireNonNull(defaultSupplier); + + ConfigElement element = at(path); + if (element == null || !element.isContainer()) { + return Objects.requireNonNull(defaultSupplier.get(), "default value supplier"); + } + + return element.asContainer(); + } + + /** + * Equivalent to {@link ConfigElement#at(String)}, but calls {@code defaultSupplier} to compute a default value + * iff the element at the path does not exist or is not a container. + * + * @param path the path to search along + * @param defaultSupplier the default value supplier, which must return a non-null value + * @return the object at the path, else the computed default value + */ + default @NotNull ConfigContainer containerAtOrDefault(@NotNull String path, + @NotNull Supplier defaultSupplier) { + return containerAtOrDefault(ConfigPath.of(path), defaultSupplier); + } + + /** + * Equivalent to {@link ConfigElement#at(ConfigPath)}, but returns {@code defaultValue} iff the element at the path + * does not exist or is not a node. + * + * @param path the path to search along + * @param defaultValue the default value + * @return the object at the path, else the default value + */ + default @NotNull ConfigNode nodeAtOrDefault(@NotNull ConfigPath path, @NotNull ConfigNode defaultValue) { + Objects.requireNonNull(defaultValue); + + ConfigElement element = at(path); + if (element == null || !element.isNode()) { + return defaultValue; + } + + return element.asNode(); + } + + /** + * Equivalent to {@link ConfigElement#at(String)}, but returns {@code defaultValue} iff the element at the path + * does not exist or is not a node. + * + * @param path the path to search along + * @param defaultValue the default value + * @return the object at the path, else the default value + */ + default @NotNull ConfigNode nodeAtOrDefault(@NotNull String path, @NotNull ConfigNode defaultValue) { + return nodeAtOrDefault(ConfigPath.of(path), defaultValue); + } + + /** + * Equivalent to {@link ConfigElement#at(ConfigPath)}, but calls {@code defaultSupplier} to compute a default value + * iff the element at the path does not exist or is not a node. + * + * @param path the path to search along + * @param defaultSupplier the default value supplier, which must return a non-null value + * @return the object at the path, else the computed default value + */ + default @NotNull ConfigNode nodeAtOrDefault(@NotNull ConfigPath path, + @NotNull Supplier defaultSupplier) { + Objects.requireNonNull(defaultSupplier); + + ConfigElement element = at(path); + if (element == null || !element.isNode()) { + return Objects.requireNonNull(defaultSupplier.get(), "default value supplier"); + } + + return element.asNode(); + } + + /** + * Equivalent to {@link ConfigElement#at(String)}, but calls {@code defaultSupplier} to compute a default value + * iff the element at the path does not exist or is not a node. + * + * @param path the path to search along + * @param defaultSupplier the default value supplier, which must return a non-null value + * @return the object at the path, else the computed default value + */ + default @NotNull ConfigNode nodeAtOrDefault(@NotNull String path, + @NotNull Supplier defaultSupplier) { + return nodeAtOrDefault(ConfigPath.of(path), defaultSupplier); + } + + /** + * Equivalent to {@link ConfigElement#at(ConfigPath)}, but returns {@code defaultValue} iff the element at the path + * does not exist or is not a list. + * + * @param path the path to search along + * @param defaultValue the default value + * @return the object at the path, else the default value + */ + default @NotNull ConfigList listAtOrDefault(@NotNull ConfigPath path, @NotNull ConfigList defaultValue) { + Objects.requireNonNull(defaultValue); + + ConfigElement element = at(path); + if (element == null || !element.isList()) { + return defaultValue; + } + + return element.asList(); + } + + /** + * Equivalent to {@link ConfigElement#at(String)}, but returns {@code defaultValue} iff the element at the path + * does not exist or is not a list. + * + * @param path the path to search along + * @param defaultValue the default value + * @return the object at the path, else the default value + */ + default @NotNull ConfigList listAtOrDefault(@NotNull String path, @NotNull ConfigList defaultValue) { + return listAtOrDefault(ConfigPath.of(path), defaultValue); + } + + /** + * Equivalent to {@link ConfigElement#at(ConfigPath)}, but calls {@code defaultSupplier} to compute a default value + * iff the element at the path does not exist or is not a list. + * + * @param path the path to search along + * @param defaultSupplier the default value supplier, which must return a non-null value + * @return the object at the path, else the computed default value + */ + default @NotNull ConfigList listAtOrDefault(@NotNull ConfigPath path, + @NotNull Supplier defaultSupplier) { + Objects.requireNonNull(defaultSupplier); + + ConfigElement element = at(path); + if (element == null || !element.isList()) { + return Objects.requireNonNull(defaultSupplier.get(), "default value supplier"); + } + + return element.asList(); + } + + /** + * Equivalent to {@link ConfigElement#at(String)}, but calls {@code defaultSupplier} to compute a default value + * iff the element at the path does not exist or is not a list. + * + * @param path the path to search along + * @param defaultSupplier the default value supplier, which must return a non-null value + * @return the object at the path, else the computed default value + */ + default @NotNull ConfigList listAtOrDefault(@NotNull String path, + @NotNull Supplier defaultSupplier) { + return listAtOrDefault(ConfigPath.of(path), defaultSupplier); + } + + /** + * Equivalent to {@link ConfigElement#at(ConfigPath)}, but returns {@code defaultValue} iff the element at the path + * does not exist or is not a boolean. + * + * @param path the path to search along + * @param defaultValue the default value + * @return the object at the path, else the default value + */ + default boolean booleanAtOrDefault(@NotNull ConfigPath path, boolean defaultValue) { + ConfigElement element = at(path); + if (element == null || !element.isBoolean()) { + return defaultValue; + } + + return element.asBoolean(); + } + + /** + * Equivalent to {@link ConfigElement#at(String)}, but returns {@code defaultValue} iff the element at the path + * does not exist or is not a boolean. + * + * @param path the path to search along + * @param defaultValue the default value + * @return the object at the path, else the default value + */ + default boolean booleanAtOrDefault(@NotNull String path, boolean defaultValue) { + return booleanAtOrDefault(ConfigPath.of(path), defaultValue); + } + + /** + * Equivalent to {@link ConfigElement#at(ConfigPath)}, but calls {@code defaultSupplier} to compute a default value + * iff the element at the path does not exist or is not a boolean. + * + * @param path the path to search along + * @param defaultSupplier the default value supplier + * @return the object at the path, else the computed default value + */ + default boolean booleanAtOrDefault(@NotNull ConfigPath path, + @NotNull BooleanSupplier defaultSupplier) { + Objects.requireNonNull(defaultSupplier); + + ConfigElement element = at(path); + if (element == null || !element.isBoolean()) { + return defaultSupplier.getAsBoolean(); + } + + return element.asBoolean(); + } + + /** + * Equivalent to {@link ConfigElement#at(String)}, but calls {@code defaultSupplier} to compute a default value + * iff the element at the path does not exist or is not a boolean. + * + * @param path the path to search along + * @param defaultSupplier the default value supplier + * @return the object at the path, else the computed default value + */ + default boolean booleanAtOrDefault(@NotNull String path, + @NotNull BooleanSupplier defaultSupplier) { + return booleanAtOrDefault(ConfigPath.of(path), defaultSupplier); + } + + /** + * Equivalent to {@link ConfigElement#at(ConfigPath)}, but returns {@code defaultValue} iff the element at the path + * does not exist or is not a number. + * + * @param path the path to search along + * @param defaultValue the default value + * @return the object at the path, else the default value + */ + default @NotNull Number numberAtOrDefault(@NotNull ConfigPath path, @NotNull Number defaultValue) { + Objects.requireNonNull(defaultValue); + + ConfigElement element = at(path); + if (element == null || !element.isNumber()) { + return defaultValue; + } + + return element.asNumber(); + } + + /** + * Equivalent to {@link ConfigElement#at(String)}, but returns {@code defaultValue} iff the element at the path + * does not exist or is not a number. + * + * @param path the path to search along + * @param defaultValue the default value + * @return the object at the path, else the default value + */ + default @NotNull Number numberAtOrDefault(@NotNull String path, @NotNull Number defaultValue) { + return numberAtOrDefault(ConfigPath.of(path), defaultValue); + } + + /** + * Equivalent to {@link ConfigElement#at(ConfigPath)}, but calls {@code defaultSupplier} to compute a default value + * iff the element at the path does not exist or is not a number. + * + * @param path the path to search along + * @param defaultSupplier the default value supplier, which must return a non-null value + * @return the object at the path, else the computed default value + */ + default @NotNull Number numberAtOrDefault(@NotNull ConfigPath path, + @NotNull Supplier defaultSupplier) { + Objects.requireNonNull(defaultSupplier); + + ConfigElement element = at(path); + if (element == null || !element.isNumber()) { + return Objects.requireNonNull(defaultSupplier.get(), "default value supplier"); + } + + return element.asNumber(); + } + + /** + * Equivalent to {@link ConfigElement#at(String)}, but calls {@code defaultSupplier} to compute a default value + * iff the element at the path does not exist or is not a number. + * + * @param path the path to search along + * @param defaultSupplier the default value supplier, which must return a non-null value + * @return the object at the path, else the computed default value + */ + default @NotNull Number numberAtOrDefault(@NotNull String path, + @NotNull Supplier defaultSupplier) { + return numberAtOrDefault(ConfigPath.of(path), defaultSupplier); + } + + /** + * Equivalent to {@link ConfigElement#at(ConfigPath)}, but returns {@code defaultValue} iff the element at the path + * does not exist or is not a string. + * + * @param path the path to search along + * @param defaultValue the default value + * @return the object at the path, else the default value + */ + default @NotNull String stringAtOrDefault(@NotNull ConfigPath path, @NotNull String defaultValue) { + Objects.requireNonNull(defaultValue); + + ConfigElement element = at(path); + if (element == null || !element.isString()) { + return defaultValue; + } + + return element.asString(); + } + + /** + * Equivalent to {@link ConfigElement#at(String)}, but returns {@code defaultValue} iff the element at the path + * does not exist or is not a string. + * + * @param path the path to search along + * @param defaultValue the default value + * @return the object at the path, else the default value + */ + default @NotNull String stringAtOrDefault(@NotNull String path, @NotNull String defaultValue) { + return stringAtOrDefault(ConfigPath.of(path), defaultValue); + } + + /** + * Equivalent to {@link ConfigElement#at(ConfigPath)}, but calls {@code defaultSupplier} to compute a default value + * iff the element at the path does not exist or is not a string. + * + * @param path the path to search along + * @param defaultSupplier the default value supplier, which must return a non-null value + * @return the object at the path, else the computed default value + */ + default @NotNull String stringAtOrDefault(@NotNull ConfigPath path, + @NotNull Supplier defaultSupplier) { + Objects.requireNonNull(defaultSupplier); + + ConfigElement element = at(path); + if (element == null || !element.isString()) { + return Objects.requireNonNull(defaultSupplier.get(), "default value supplier"); + } + + return element.asString(); + } + + /** + * Equivalent to {@link ConfigElement#at(String)}, but calls {@code defaultSupplier} to compute a default value + * iff the element at the path does not exist or is not a string. + * + * @param path the path to search along + * @param defaultSupplier the default value supplier, which must return a non-null value + * @return the object at the path, else the computed default value + */ + default @NotNull String stringAtOrDefault(@NotNull String path, + @NotNull Supplier defaultSupplier) { + return stringAtOrDefault(ConfigPath.of(path), defaultSupplier); + } + /** * Determines if this ConfigElement represents a container (holds other ConfigElements). * diff --git a/ethylene-core/src/main/java/com/github/steanky/ethylene/core/collection/ConfigList.java b/ethylene-core/src/main/java/com/github/steanky/ethylene/core/collection/ConfigList.java index 7288c37..b030fb7 100644 --- a/ethylene-core/src/main/java/com/github/steanky/ethylene/core/collection/ConfigList.java +++ b/ethylene-core/src/main/java/com/github/steanky/ethylene/core/collection/ConfigList.java @@ -7,6 +7,8 @@ import java.util.List; import java.util.Objects; +import java.util.function.BooleanSupplier; +import java.util.function.Supplier; /** * Represents an ordered collection of {@link ConfigElement} objects. ConfigList does not support null values. @@ -111,6 +113,269 @@ default void addBoolean(boolean value) { add(ConfigPrimitive.of(value)); } + /** + * Gets a value if it is in-bounds and the expected type; else returns the non-null default value. + * + * @param index the index + * @param defaultValue the default value + * @return the value present in this node if it is the right type and in-bounds; else the default value + */ + default @NotNull ConfigContainer getContainerOrDefault(int index, @NotNull ConfigContainer defaultValue) { + Objects.requireNonNull(defaultValue); + if (index < 0 || index >= size()) { + return defaultValue; + } + + ConfigElement element = get(index); + if (!element.isContainer()) { + return defaultValue; + } + + return element.asContainer(); + } + + /** + * Gets a value if it is in-bounds and the expected type; else computes and returns the non-null default value. + * + * @param index the index + * @param defaultValueSupplier the default value supplier + * @return the value present in this node if it is the right type and in-bounds; else the non-null computed default + * value + */ + default @NotNull ConfigContainer getContainerOrDefault(int index, + @NotNull Supplier defaultValueSupplier) { + Objects.requireNonNull(defaultValueSupplier); + if (index < 0 || index >= size()) { + return Objects.requireNonNull(defaultValueSupplier.get(), "default value supplier"); + } + + ConfigElement element = get(index); + if (!element.isContainer()) { + return Objects.requireNonNull(defaultValueSupplier.get(), "default value supplier"); + } + + return element.asContainer(); + } + + /** + * Gets a value if it is in-bounds and the expected type; else returns the non-null default value. + * + * @param index the index + * @param defaultValue the default value + * @return the value present in this node if it is the right type and in-bounds; else the default value + */ + default @NotNull ConfigNode getNodeOrDefault(int index, @NotNull ConfigNode defaultValue) { + Objects.requireNonNull(defaultValue); + if (index < 0 || index >= size()) { + return defaultValue; + } + + ConfigElement element = get(index); + if (!element.isNode()) { + return defaultValue; + } + + return element.asNode(); + } + + /** + * Gets a value if it is in-bounds and the expected type; else computes and returns the non-null default value. + * + * @param index the index + * @param defaultValueSupplier the default value supplier + * @return the value present in this node if it is the right type and in-bounds; else the non-null computed default + * value + */ + default @NotNull ConfigNode getNodeOrDefault(int index, + @NotNull Supplier defaultValueSupplier) { + Objects.requireNonNull(defaultValueSupplier); + if (index < 0 || index >= size()) { + return Objects.requireNonNull(defaultValueSupplier.get(), "default value supplier"); + } + + ConfigElement element = get(index); + if (!element.isNode()) { + return Objects.requireNonNull(defaultValueSupplier.get(), "default value supplier"); + } + + return element.asNode(); + } + + /** + * Gets a value if it is in-bounds and the expected type; else returns the non-null default value. + * + * @param index the index + * @param defaultValue the default value + * @return the value present in this node if it is the right type and in-bounds; else the default value + */ + default @NotNull ConfigList getListOrDefault(int index, @NotNull ConfigList defaultValue) { + Objects.requireNonNull(defaultValue); + if (index < 0 || index >= size()) { + return defaultValue; + } + + ConfigElement element = get(index); + if (!element.isList()) { + return defaultValue; + } + + return element.asList(); + } + + /** + * Gets a value if it is in-bounds and the expected type; else computes and returns the non-null default value. + * + * @param index the index + * @param defaultValueSupplier the default value supplier + * @return the value present in this node if it is the right type and in-bounds; else the non-null computed default + * value + */ + default @NotNull ConfigList getListOrDefault(int index, + @NotNull Supplier defaultValueSupplier) { + Objects.requireNonNull(defaultValueSupplier); + if (index < 0 || index >= size()) { + return Objects.requireNonNull(defaultValueSupplier.get(), "default value supplier"); + } + + ConfigElement element = get(index); + if (!element.isList()) { + return Objects.requireNonNull(defaultValueSupplier.get(), "default value supplier"); + } + + return element.asList(); + } + + /** + * Gets a value if it is in-bounds and the expected type; else returns the default value. + * + * @param index the index + * @param defaultValue the default value + * @return the value present in this node if it is the right type and in-bounds; else the default value + */ + default boolean getBooleanOrDefault(int index, boolean defaultValue) { + if (index < 0 || index >= size()) { + return defaultValue; + } + + ConfigElement element = get(index); + if (!element.isBoolean()) { + return defaultValue; + } + + return element.asBoolean(); + } + + /** + * Gets a value if it is in-bounds and the expected type; else computes and returns the default value. + * + * @param index the index + * @param defaultValueSupplier the default value supplier + * @return the value present in this node if it is the right type and in-bounds; else the non-null computed default + * value + */ + default boolean getBooleanOrDefault(int index, + @NotNull BooleanSupplier defaultValueSupplier) { + Objects.requireNonNull(defaultValueSupplier); + if (index < 0 || index >= size()) { + return defaultValueSupplier.getAsBoolean(); + } + + ConfigElement element = get(index); + if (!element.isBoolean()) { + return defaultValueSupplier.getAsBoolean(); + } + + return element.asBoolean(); + } + + /** + * Gets a value if it is in-bounds and the expected type; else returns the non-null default value. + * + * @param index the index + * @param defaultValue the default value + * @return the value present in this node if it is the right type and in-bounds; else the default value + */ + default @NotNull Number getNumberOrDefault(int index, @NotNull Number defaultValue) { + Objects.requireNonNull(defaultValue); + if (index < 0 || index >= size()) { + return defaultValue; + } + + ConfigElement element = get(index); + if (!element.isNumber()) { + return defaultValue; + } + + return element.asNumber(); + } + + /** + * Gets a value if it is in-bounds and the expected type; else computes and returns the non-null default value. + * + * @param index the index + * @param defaultValueSupplier the default value supplier + * @return the value present in this node if it is the right type and in-bounds; else the non-null computed default + * value + */ + default @NotNull Number getNumberOrDefault(int index, + @NotNull Supplier defaultValueSupplier) { + Objects.requireNonNull(defaultValueSupplier); + if (index < 0 || index >= size()) { + return Objects.requireNonNull(defaultValueSupplier.get(), "default value supplier"); + } + + ConfigElement element = get(index); + if (!element.isNumber()) { + return Objects.requireNonNull(defaultValueSupplier.get(), "default value supplier"); + } + + return element.asNumber(); + } + + /** + * Gets a value if it is in-bounds and the expected type; else returns the non-null default value. + * + * @param index the index + * @param defaultValue the default value + * @return the value present in this node if it is the right type and in-bounds; else the default value + */ + default @NotNull String getStringOrDefault(int index, @NotNull String defaultValue) { + Objects.requireNonNull(defaultValue); + if (index < 0 || index >= size()) { + return defaultValue; + } + + ConfigElement element = get(index); + if (!element.isString()) { + return defaultValue; + } + + return element.asString(); + } + + /** + * Gets a value if it is in-bounds and the expected type; else computes and returns the non-null default value. + * + * @param index the index + * @param defaultValueSupplier the default value supplier + * @return the value present in this node if it is the right type and in-bounds; else the non-null computed default + * value + */ + default @NotNull String getStringOrDefault(int index, + @NotNull Supplier defaultValueSupplier) { + Objects.requireNonNull(defaultValueSupplier); + if (index < 0 || index >= size()) { + return Objects.requireNonNull(defaultValueSupplier.get(), "default value supplier"); + } + + ConfigElement element = get(index); + if (!element.isString()) { + return Objects.requireNonNull(defaultValueSupplier.get(), "default value supplier"); + } + + return element.asString(); + } + @Override default @NotNull ConfigList copy() { return (ConfigList) ConfigContainer.super.copy(); diff --git a/ethylene-core/src/main/java/com/github/steanky/ethylene/core/collection/ConfigNode.java b/ethylene-core/src/main/java/com/github/steanky/ethylene/core/collection/ConfigNode.java index 08f904f..cd8ee9f 100644 --- a/ethylene-core/src/main/java/com/github/steanky/ethylene/core/collection/ConfigNode.java +++ b/ethylene-core/src/main/java/com/github/steanky/ethylene/core/collection/ConfigNode.java @@ -8,6 +8,8 @@ import java.util.Map; import java.util.Objects; +import java.util.function.BooleanSupplier; +import java.util.function.Supplier; /** *

Represents some arbitrary configuration data in a tree-like structure. ConfigNode objects are mutable data @@ -169,6 +171,215 @@ default void putBoolean(@NotNull String key, boolean value) { put(key, ConfigPrimitive.of(value)); } + /** + * Gets a value if it is present and the expected type; else returns the non-null default value. + * + * @param key the key + * @param defaultValue the default value + * @return the value present in this node if it is the right type; else the default value + */ + default @NotNull ConfigContainer getContainerOrDefault(@NotNull String key, @NotNull ConfigContainer defaultValue) { + Objects.requireNonNull(defaultValue); + ConfigElement element = get(key); + if (element == null || !element.isContainer()) { + return defaultValue; + } + + return element.asContainer(); + } + + /** + * Gets a value if it is present and the expected type; else computes and returns the non-null default value. + * + * @param key the key + * @param defaultValueSupplier the default value supplier + * @return the value present in this node if it is the right type; else the non-null computed default value + */ + default @NotNull ConfigContainer getContainerOrDefault(@NotNull String key, + @NotNull Supplier defaultValueSupplier) { + Objects.requireNonNull(defaultValueSupplier); + ConfigElement element = get(key); + if (element == null || !element.isContainer()) { + return Objects.requireNonNull(defaultValueSupplier.get(), "default value supplier"); + } + + return element.asContainer(); + } + + /** + * Gets a value if it is present and the expected type; else returns the non-null default value. + * + * @param key the key + * @param defaultValue the default value + * @return the value present in this node if it is the right type; else the default value + */ + default @NotNull ConfigNode getNodeOrDefault(@NotNull String key, @NotNull ConfigNode defaultValue) { + Objects.requireNonNull(defaultValue); + ConfigElement element = get(key); + if (element == null || !element.isNode()) { + return defaultValue; + } + + return element.asNode(); + } + + /** + * Gets a value if it is present and the expected type; else computes and returns the non-null default value. + * + * @param key the key + * @param defaultValueSupplier the default value supplier + * @return the value present in this node if it is the right type; else the non-null computed default value + */ + default @NotNull ConfigNode getNodeOrDefault(@NotNull String key, + @NotNull Supplier defaultValueSupplier) { + Objects.requireNonNull(defaultValueSupplier); + ConfigElement element = get(key); + if (element == null || !element.isNode()) { + return Objects.requireNonNull(defaultValueSupplier.get(), "default value supplier"); + } + + return element.asNode(); + } + + /** + * Gets a value if it is present and the expected type; else returns the non-null default value. + * + * @param key the key + * @param defaultValue the default value + * @return the value present in this node if it is the right type; else the default value + */ + default @NotNull ConfigList getListOrDefault(@NotNull String key, @NotNull ConfigList defaultValue) { + Objects.requireNonNull(defaultValue); + ConfigElement element = get(key); + if (element == null || !element.isList()) { + return defaultValue; + } + + return element.asList(); + } + + /** + * Gets a value if it is present and the expected type; else computes and returns the non-null default value. + * + * @param key the key + * @param defaultValueSupplier the default value supplier + * @return the value present in this node if it is the right type; else the non-null computed default value + */ + default @NotNull ConfigList getListOrDefault(@NotNull String key, + @NotNull Supplier defaultValueSupplier) { + Objects.requireNonNull(defaultValueSupplier); + ConfigElement element = get(key); + if (element == null || !element.isList()) { + return Objects.requireNonNull(defaultValueSupplier.get(), "default value supplier"); + } + + return element.asList(); + } + + /** + * Gets a value if it is present and the expected type; else returns the non-null default value. + * + * @param key the key + * @param defaultValue the default value + * @return the value present in this node if it is the right type; else the default value + */ + default boolean getBooleanOrDefault(@NotNull String key, boolean defaultValue) { + ConfigElement element = get(key); + if (element == null || !element.isBoolean()) { + return defaultValue; + } + + return element.asBoolean(); + } + + /** + * Gets a value if it is present and the expected type; else computes and returns the non-null default value. + * + * @param key the key + * @param defaultValueSupplier the default value supplier + * @return the value present in this node if it is the right type; else the non-null computed default value + */ + default boolean getBooleanOrDefault(@NotNull String key, + @NotNull BooleanSupplier defaultValueSupplier) { + Objects.requireNonNull(defaultValueSupplier); + ConfigElement element = get(key); + if (element == null || !element.isBoolean()) { + return defaultValueSupplier.getAsBoolean(); + } + + return element.asBoolean(); + } + + /** + * Gets a value if it is present and the expected type; else returns the non-null default value. + * + * @param key the key + * @param defaultValue the default value + * @return the value present in this node if it is the right type; else the default value + */ + default @NotNull Number getNumberOrDefault(@NotNull String key, @NotNull Number defaultValue) { + Objects.requireNonNull(defaultValue); + ConfigElement element = get(key); + if (element == null || !element.isNumber()) { + return defaultValue; + } + + return element.asNumber(); + } + + /** + * Gets a value if it is present and the expected type; else computes and returns the non-null default value. + * + * @param key the key + * @param defaultValueSupplier the default value supplier + * @return the value present in this node if it is the right type; else the non-null computed default value + */ + default @NotNull Number getNumberOrDefault(@NotNull String key, + @NotNull Supplier defaultValueSupplier) { + Objects.requireNonNull(defaultValueSupplier); + ConfigElement element = get(key); + if (element == null || !element.isNumber()) { + return Objects.requireNonNull(defaultValueSupplier.get(), "default value supplier"); + } + + return element.asNumber(); + } + + /** + * Gets a value if it is present and the expected type; else returns the non-null default value. + * + * @param key the key + * @param defaultValue the default value + * @return the value present in this node if it is the right type; else the default value + */ + default @NotNull String getStringOrDefault(@NotNull String key, @NotNull String defaultValue) { + Objects.requireNonNull(defaultValue); + ConfigElement element = get(key); + if (element == null || !element.isString()) { + return defaultValue; + } + + return element.asString(); + } + + /** + * Gets a value if it is present and the expected type; else computes and returns the non-null default value. + * + * @param key the key + * @param defaultValueSupplier the default value supplier + * @return the value present in this node if it is the right type; else the non-null computed default value + */ + default @NotNull String getStringOrDefault(@NotNull String key, + @NotNull Supplier defaultValueSupplier) { + Objects.requireNonNull(defaultValueSupplier); + ConfigElement element = get(key); + if (element == null || !element.isString()) { + return Objects.requireNonNull(defaultValueSupplier.get(), "default value supplier"); + } + + return element.asString(); + } + @Override default @NotNull ConfigNode copy() { return (ConfigNode) ConfigContainer.super.copy();