1
mirror of https://github.com/CarmJos/EasyConfiguration.git synced 2026-06-04 18:48:20 +08:00

feat(map): Finished Map value builders.

This commit is contained in:
2025-02-15 07:20:59 +08:00
parent c79b94b719
commit aedc6cb439
17 changed files with 492 additions and 48 deletions
@@ -4,6 +4,7 @@ import org.jetbrains.annotations.NotNull;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
/** /**
@@ -14,21 +14,21 @@ import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
public abstract class AbstractConfigBuilder< public abstract class AbstractConfigBuilder<
TYPE, RESULT extends ConfigValue<TYPE>, PROVIDER extends ConfigurationHolder<?>, TYPE, RESULT extends ConfigValue<TYPE>, HOLDER extends ConfigurationHolder<?>,
SELF extends AbstractConfigBuilder<TYPE, RESULT, PROVIDER, SELF> SELF extends AbstractConfigBuilder<TYPE, RESULT, HOLDER, SELF>
> { > {
protected final Class<? super PROVIDER> providerClass; protected final Class<? super HOLDER> providerClass;
protected final ValueType<TYPE> type; protected final ValueType<TYPE> type;
protected @Nullable PROVIDER provider; protected @Nullable HOLDER holder;
protected @Nullable String path; protected @Nullable String path;
protected @NotNull Supplier<TYPE> defaultValueSupplier = () -> null; protected @NotNull Supplier<@Nullable TYPE> defaultValueSupplier = () -> null;
protected @NotNull BiConsumer<ConfigurationHolder<?>, String> initializer = (provider, path) -> { protected @NotNull BiConsumer<ConfigurationHolder<?>, String> initializer = (h, p) -> {
}; };
protected AbstractConfigBuilder(Class<? super PROVIDER> providerClass, ValueType<TYPE> type) { protected AbstractConfigBuilder(Class<? super HOLDER> providerClass, ValueType<TYPE> type) {
this.providerClass = providerClass; this.providerClass = providerClass;
this.type = type; this.type = type;
} }
@@ -41,8 +41,8 @@ public abstract class AbstractConfigBuilder<
public abstract @NotNull RESULT build(); public abstract @NotNull RESULT build();
public @NotNull SELF holder(@Nullable PROVIDER provider) { public @NotNull SELF holder(@Nullable HOLDER holder) {
this.provider = provider; this.holder = holder;
return self(); return self();
} }
@@ -61,7 +61,7 @@ public abstract class AbstractConfigBuilder<
} }
public @NotNull SELF append(@NotNull Consumer<ConfigurationHolder<?>> initializer) { public @NotNull SELF append(@NotNull Consumer<ConfigurationHolder<?>> initializer) {
return append((provider, path) -> initializer.accept(provider)); return append((provider, valuePath) -> initializer.accept(provider));
} }
public @NotNull SELF defaults(@Nullable TYPE defaultValue) { public @NotNull SELF defaults(@Nullable TYPE defaultValue) {
@@ -74,17 +74,17 @@ public abstract class AbstractConfigBuilder<
} }
public <M> @NotNull SELF meta(@NotNull Consumer<@NotNull ConfigurationMetaHolder> metaConsumer) { public <M> @NotNull SELF meta(@NotNull Consumer<@NotNull ConfigurationMetaHolder> metaConsumer) {
return append((provider, path) -> metaConsumer.accept(provider.metadata(path))); return append((h, p) -> metaConsumer.accept(h.metadata(p)));
} }
public <M> @NotNull SELF meta(@NotNull ConfigurationMetadata<M> type, @Nullable M value) { public <M> @NotNull SELF meta(@NotNull ConfigurationMetadata<M> type, @Nullable M value) {
return meta(holder -> holder.set(type, value)); return meta(h -> h.set(type, value));
} }
protected @NotNull ValueManifest<TYPE> buildManifest() { protected @NotNull ValueManifest<TYPE> buildManifest() {
return new ValueManifest<>( return new ValueManifest<>(
type(), this.defaultValueSupplier, this.initializer, type(), this.defaultValueSupplier, this.initializer,
this.provider, this.path this.holder, this.path
); );
} }
@@ -3,6 +3,7 @@ package cc.carm.lib.configuration.builder.impl;
import cc.carm.lib.configuration.adapter.ValueAdapter; import cc.carm.lib.configuration.adapter.ValueAdapter;
import cc.carm.lib.configuration.adapter.ValueType; import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.builder.CommonConfigBuilder; import cc.carm.lib.configuration.builder.CommonConfigBuilder;
import cc.carm.lib.configuration.function.DataConsumer;
import cc.carm.lib.configuration.function.DataFunction; import cc.carm.lib.configuration.function.DataFunction;
import cc.carm.lib.configuration.function.ValueHandler; import cc.carm.lib.configuration.function.ValueHandler;
import cc.carm.lib.configuration.source.section.ConfigureSection; import cc.carm.lib.configuration.source.section.ConfigureSection;
@@ -11,7 +12,6 @@ import org.jetbrains.annotations.NotNull;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Consumer;
public abstract class AbstractSectionBuilder< public abstract class AbstractSectionBuilder<
TYPE, PARAM, TYPE, PARAM,
@@ -19,12 +19,13 @@ public abstract class AbstractSectionBuilder<
SELF extends AbstractSectionBuilder<TYPE, PARAM, RESULT, SELF> SELF extends AbstractSectionBuilder<TYPE, PARAM, RESULT, SELF>
> extends CommonConfigBuilder<TYPE, RESULT, SELF> { > extends CommonConfigBuilder<TYPE, RESULT, SELF> {
protected final @NotNull ValueType<PARAM> paramType; protected final @NotNull ValueType<PARAM> paramType;
protected @NotNull ValueHandler<ConfigureSection, PARAM> parser; protected @NotNull ValueHandler<ConfigureSection, PARAM> parser;
protected @NotNull ValueHandler<PARAM, ? extends Map<String, Object>> serializer; protected @NotNull ValueHandler<PARAM, ? extends Map<String, Object>> serializer;
public AbstractSectionBuilder(@NotNull ValueType<TYPE> type, @NotNull ValueType<PARAM> paramType, protected AbstractSectionBuilder(@NotNull ValueType<TYPE> type, @NotNull ValueType<PARAM> paramType,
@NotNull ValueHandler<ConfigureSection, PARAM> parser, @NotNull ValueHandler<ConfigureSection, PARAM> parser,
@NotNull ValueHandler<PARAM, ? extends Map<String, Object>> serializer) { @NotNull ValueHandler<PARAM, ? extends Map<String, Object>> serializer) {
super(type); super(type);
@@ -51,7 +52,7 @@ public abstract class AbstractSectionBuilder<
return self(); return self();
} }
public @NotNull SELF serialize(Consumer<Map<String, Object>> serializer) { public @NotNull SELF serialize(DataConsumer<Map<String, Object>> serializer) {
return serialize((p, value) -> { return serialize((p, value) -> {
Map<String, Object> map = new LinkedHashMap<>(); Map<String, Object> map = new LinkedHashMap<>();
serializer.accept(map); serializer.accept(map);
@@ -71,4 +72,5 @@ public abstract class AbstractSectionBuilder<
return map == null || map.isEmpty() ? null : map; return map == null || map.isEmpty() ? null : map;
}); });
} }
} }
@@ -18,7 +18,7 @@ public abstract class AbstractSourceBuilder<
protected @NotNull ValueHandler<SOURCE, PARAM> valueParser; protected @NotNull ValueHandler<SOURCE, PARAM> valueParser;
protected @NotNull ValueHandler<PARAM, SOURCE> valueSerializer; protected @NotNull ValueHandler<PARAM, SOURCE> valueSerializer;
public AbstractSourceBuilder(@NotNull ValueType<V> type, protected AbstractSourceBuilder(@NotNull ValueType<V> type,
@NotNull ValueType<SOURCE> sourceType, @NotNull ValueType<PARAM> paramType, @NotNull ValueType<SOURCE> sourceType, @NotNull ValueType<PARAM> paramType,
@NotNull ValueHandler<SOURCE, PARAM> parser, @NotNull ValueHandler<SOURCE, PARAM> parser,
@NotNull ValueHandler<PARAM, SOURCE> serializer) { @NotNull ValueHandler<PARAM, SOURCE> serializer) {
@@ -19,15 +19,25 @@ public class ConfigListBuilder<V> {
} }
public <S> @NotNull SourceListBuilder<S, V> from(@NotNull ValueType<S> sourceType) { public <S> @NotNull SourceListBuilder<S, V> from(@NotNull ValueType<S> sourceType) {
return new SourceListBuilder<>(sourceType, type, ValueHandler.required(), ValueHandler.required(), ArrayList::new); return new SourceListBuilder<>(
ArrayList::new, sourceType, type,
ValueHandler.required(type),
ValueHandler.required(sourceType)
);
} }
public @NotNull SourceListBuilder<String, V> fromString() { public @NotNull SourceListBuilder<String, V> fromString() {
return new SourceListBuilder<>(ValueType.STRING, type, ValueHandler.required(), ValueHandler.stringValue(), ArrayList::new); return new SourceListBuilder<>(
ArrayList::new, ValueType.STRING, type,
ValueHandler.required(type), ValueHandler.stringValue()
);
} }
public @NotNull SectionListBuilder<V> fromSection() { public @NotNull SectionListBuilder<V> fromSection() {
return new SectionListBuilder<>(type, ValueHandler.required(), ValueHandler.required(), ArrayList::new); return new SectionListBuilder<>(
ArrayList::new, type,
ValueHandler.required(type), ValueHandler.required()
);
} }
@@ -14,10 +14,10 @@ public class SectionListBuilder<V> extends AbstractSectionBuilder<List<V>, V, Co
protected @NotNull Supplier<? extends List<V>> constructor; protected @NotNull Supplier<? extends List<V>> constructor;
public SectionListBuilder(@NotNull ValueType<V> paramType, public SectionListBuilder(@NotNull Supplier<? extends List<V>> constructor,
@NotNull ValueType<V> paramType,
@NotNull ValueHandler<ConfigureSection, V> parser, @NotNull ValueHandler<ConfigureSection, V> parser,
@NotNull ValueHandler<V, ? extends Map<String, Object>> serializer, @NotNull ValueHandler<V, ? extends Map<String, Object>> serializer) {
@NotNull Supplier<? extends List<V>> constructor) {
super(new ValueType<List<V>>() { super(new ValueType<List<V>>() {
}, paramType, parser, serializer); }, paramType, parser, serializer);
this.constructor = constructor; this.constructor = constructor;
@@ -17,9 +17,9 @@ public class SourceListBuilder<SOURCE, V>
protected @NotNull Supplier<? extends List<V>> constructor; protected @NotNull Supplier<? extends List<V>> constructor;
public SourceListBuilder(@NotNull ValueType<SOURCE> sourceType, @NotNull ValueType<V> paramType, public SourceListBuilder(@NotNull Supplier<? extends List<V>> constructor,
@NotNull ValueHandler<SOURCE, V> parser, @NotNull ValueHandler<V, SOURCE> serializer, @NotNull ValueType<SOURCE> sourceType, @NotNull ValueType<V> paramType,
@NotNull Supplier<? extends List<V>> constructor) { @NotNull ValueHandler<SOURCE, V> parser, @NotNull ValueHandler<V, SOURCE> serializer) {
super(new ValueType<List<V>>() { super(new ValueType<List<V>>() {
}, sourceType, paramType, parser, serializer); }, sourceType, paramType, parser, serializer);
this.constructor = constructor; this.constructor = constructor;
@@ -0,0 +1,80 @@
package cc.carm.lib.configuration.builder.map;
import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.function.ValueHandler;
import cc.carm.lib.configuration.source.section.ConfigureSection;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
import java.util.function.Supplier;
public class ConfigMapBuilder<M extends Map<K, V>, K, V> {
protected final @NotNull Supplier<@NotNull M> constructor;
protected final @NotNull ValueType<K> keyType;
protected final @NotNull ValueType<V> valueType;
public ConfigMapBuilder(@NotNull Supplier<@NotNull M> constructor,
@NotNull ValueType<K> keyType, @NotNull ValueType<V> valueType) {
this.constructor = constructor;
this.keyType = keyType;
this.valueType = valueType;
}
public <W extends Map<K, V>> ConfigMapBuilder<W, K, V> constructor(@NotNull Supplier<W> supplier) {
return new ConfigMapBuilder<>(supplier, keyType, valueType);
}
public @NotNull <S> SourceMapBuilder<M, S, K, V> from(@NotNull Class<S> clazz) {
return from(ValueType.of(clazz));
}
public @NotNull <S> SourceMapBuilder<M, S, K, V> from(@NotNull ValueType<S> sourceType) {
return from(
sourceType,
ValueHandler.required(keyType), ValueHandler.stringValue(),
ValueHandler.required(valueType), ValueHandler.required()
);
}
public <S> @NotNull SourceMapBuilder<M, S, K, V> from(@NotNull ValueType<S> sourceType,
@NotNull ValueHandler<String, K> keyParser,
@NotNull ValueHandler<K, String> keySerializer,
@NotNull ValueHandler<S, V> valueParser,
@NotNull ValueHandler<V, S> valueSerializer) {
return new SourceMapBuilder<>(
this.constructor, sourceType, keyType, valueType,
keyParser, keySerializer, valueParser, valueSerializer
);
}
public @NotNull SourceMapBuilder<M, String, K, V> fromString() {
return from(
ValueType.STRING,
ValueHandler.required(keyType), ValueHandler.stringValue(),
ValueHandler.required(valueType), ValueHandler.stringValue()
);
}
public @NotNull SectionMapBuilder<M, K, V> fromSection() {
return fromSection(
ValueHandler.required(keyType), ValueHandler.stringValue(),
ValueHandler.required(valueType), ValueHandler.required()
);
}
public @NotNull SectionMapBuilder<M, K, V> fromSection(
@NotNull ValueHandler<String, K> keyParser,
@NotNull ValueHandler<K, String> keySerializer,
@NotNull ValueHandler<ConfigureSection, V> valueParser,
@NotNull ValueHandler<V, Map<String, Object>> valueSerializer
) {
return new SectionMapBuilder<>(
this.constructor, keyType, valueType,
keyParser, keySerializer, valueParser, valueSerializer
);
}
}
@@ -0,0 +1,48 @@
package cc.carm.lib.configuration.builder.map;
import cc.carm.lib.configuration.adapter.ValueType;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.function.Supplier;
public class ConfigMapCreator<K, V> {
protected final @NotNull ValueType<K> keyType;
protected final @NotNull ValueType<V> valueType;
public ConfigMapCreator(@NotNull ValueType<K> keyType, @NotNull ValueType<V> valueType) {
this.keyType = keyType;
this.valueType = valueType;
}
public <M extends Map<K, V>> @NotNull ConfigMapBuilder<M, K, V> constructor(@NotNull Supplier<@NotNull M> mapSuppler) {
return new ConfigMapBuilder<>(mapSuppler, keyType, valueType);
}
public <W extends Map<K, V>> @NotNull ConfigMapBuilder<W, K, V> constructor(@NotNull Class<W> type) {
return constructor(() -> {
try {
return type.getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
public @NotNull ConfigMapBuilder<HashMap<K, V>, K, V> asHashMap() {
return constructor(HashMap::new);
}
public @NotNull ConfigMapBuilder<LinkedHashMap<K, V>, K, V> asLinkedMap() {
return constructor(LinkedHashMap::new);
}
public @NotNull ConfigMapBuilder<TreeMap<K, V>, K, V> asTreeMap() {
return constructor(TreeMap::new);
}
}
@@ -0,0 +1,95 @@
package cc.carm.lib.configuration.builder.map;
import cc.carm.lib.configuration.adapter.ValueAdapter;
import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.builder.impl.AbstractSectionBuilder;
import cc.carm.lib.configuration.function.DataFunction;
import cc.carm.lib.configuration.function.ValueHandler;
import cc.carm.lib.configuration.source.section.ConfigureSection;
import cc.carm.lib.configuration.value.standard.ConfiguredMap;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class SectionMapBuilder<MAP extends Map<K, V>, K, V>
extends AbstractSectionBuilder<
Map<K, V>, V, ConfiguredMap<K, V>,
SectionMapBuilder<MAP, K, V>
> {
protected final @NotNull ValueType<K> keyType;
protected @NotNull Supplier<? extends MAP> constructor;
protected @NotNull ValueHandler<String, K> keyParser;
protected @NotNull ValueHandler<K, String> keySerializer;
public SectionMapBuilder(@NotNull Supplier<? extends MAP> constructor,
@NotNull ValueType<K> keyType, @NotNull ValueType<V> valueType,
@NotNull ValueHandler<String, K> keyParser,
@NotNull ValueHandler<K, String> keySerializer,
@NotNull ValueHandler<ConfigureSection, V> valueParser,
@NotNull ValueHandler<V, Map<String, Object>> valueSerializer) {
super(new ValueType<Map<K, V>>() {
}, valueType, valueParser, valueSerializer);
this.keyType = keyType;
this.constructor = constructor;
this.keyParser = keyParser;
this.keySerializer = keySerializer;
}
@Override
protected @NotNull SectionMapBuilder<MAP, K, V> self() {
return this;
}
public @NotNull SectionMapBuilder<MAP, K, V> parseKey(@NotNull DataFunction<String, K> keyParser) {
return parseKey((holder, data) -> keyParser.handle(data));
}
public @NotNull SectionMapBuilder<MAP, K, V> parseKey(@NotNull ValueHandler<String, K> keyParser) {
this.keyParser = keyParser;
return this;
}
public @NotNull SectionMapBuilder<MAP, K, V> serializeKey(@NotNull DataFunction<K, String> keySerializer) {
return serializeKey((holder, data) -> keySerializer.handle(data));
}
public @NotNull SectionMapBuilder<MAP, K, V> serializeKey(@NotNull ValueHandler<K, String> keySerializer) {
this.keySerializer = keySerializer;
return this;
}
public @NotNull SectionMapBuilder<MAP, K, V> defaults(@NotNull MAP defaults) {
return defaults(() -> defaults);
}
public @NotNull SectionMapBuilder<MAP, K, V> defaults(@NotNull Consumer<MAP> defaults) {
return defaults(() -> {
MAP map = this.constructor.get();
defaults.accept(map);
return map;
});
}
public @NotNull ValueAdapter<K> buildKeyAdapter() {
return new ValueAdapter<>(this.keyType)
.parser((holder, type, data) -> {
String source = holder.deserialize(String.class, data);
return this.keyParser.handle(holder, source);
})
.serializer((holder, type, data) -> {
String source = this.keySerializer.handle(holder, data);
return holder.serialize(source);
});
}
@Override
public @NotNull ConfiguredMap<K, V> build() {
return new ConfiguredMap<>(buildManifest(), this.constructor, buildKeyAdapter(), this.buildAdapter());
}
}
@@ -0,0 +1,91 @@
package cc.carm.lib.configuration.builder.map;
import cc.carm.lib.configuration.adapter.ValueAdapter;
import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.builder.impl.AbstractSourceBuilder;
import cc.carm.lib.configuration.function.DataFunction;
import cc.carm.lib.configuration.function.ValueHandler;
import cc.carm.lib.configuration.value.standard.ConfiguredMap;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class SourceMapBuilder<MAP extends Map<K, V>, SOURCE, K, V>
extends AbstractSourceBuilder<
Map<K, V>, SOURCE, V, ConfiguredMap<K, V>,
SourceMapBuilder<MAP, SOURCE, K, V>
> {
protected final @NotNull ValueType<K> keyType;
protected @NotNull Supplier<? extends MAP> constructor;
protected @NotNull ValueHandler<String, K> keyParser;
protected @NotNull ValueHandler<K, String> keySerializer;
public SourceMapBuilder(@NotNull Supplier<? extends MAP> constructor, @NotNull ValueType<SOURCE> sourceType,
@NotNull ValueType<K> keyType, @NotNull ValueType<V> valueType,
@NotNull ValueHandler<String, K> keyParser, @NotNull ValueHandler<K, String> keySerializer,
@NotNull ValueHandler<SOURCE, V> valueParser, @NotNull ValueHandler<V, SOURCE> valueSerializer) {
super(new ValueType<Map<K, V>>() {
}, sourceType, valueType, valueParser, valueSerializer);
this.keyType = keyType;
this.constructor = constructor;
this.keyParser = keyParser;
this.keySerializer = keySerializer;
}
@Override
protected @NotNull SourceMapBuilder<MAP, SOURCE, K, V> self() {
return this;
}
public @NotNull SourceMapBuilder<MAP, SOURCE, K, V> defaults(@NotNull MAP defaults) {
return defaults(() -> defaults);
}
public @NotNull SourceMapBuilder<MAP, SOURCE, K, V> defaults(@NotNull Consumer<MAP> defaults) {
return defaults(() -> {
MAP map = this.constructor.get();
defaults.accept(map);
return map;
});
}
public @NotNull SourceMapBuilder<MAP, SOURCE, K, V> parseKey(@NotNull DataFunction<String, K> keyParser) {
return parseKey((holder, data) -> keyParser.handle(data));
}
public @NotNull SourceMapBuilder<MAP, SOURCE, K, V> parseKey(@NotNull ValueHandler<String, K> keyParser) {
this.keyParser = keyParser;
return this;
}
public @NotNull SourceMapBuilder<MAP, SOURCE, K, V> serializeKey(@NotNull DataFunction<K, String> keySerializer) {
return serializeKey((holder, data) -> keySerializer.handle(data));
}
public @NotNull SourceMapBuilder<MAP, SOURCE, K, V> serializeKey(@NotNull ValueHandler<K, String> keySerializer) {
this.keySerializer = keySerializer;
return this;
}
public @NotNull ValueAdapter<K> buildKeyAdapter() {
return new ValueAdapter<>(this.keyType)
.parser((holder, type, data) -> {
String source = holder.deserialize(String.class, data);
return this.keyParser.handle(holder, source);
})
.serializer((holder, type, data) -> {
String source = this.keySerializer.handle(holder, data);
return holder.serialize(source);
});
}
@Override
public @NotNull ConfiguredMap<K, V> build() {
return new ConfiguredMap<>(buildManifest(), this.constructor, buildKeyAdapter(), this.buildAdapter());
}
}
@@ -1,6 +1,7 @@
package cc.carm.lib.configuration.builder.value; package cc.carm.lib.configuration.builder.value;
import cc.carm.lib.configuration.adapter.ValueType; import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.builder.impl.AbstractSectionBuilder;
import cc.carm.lib.configuration.function.ValueHandler; import cc.carm.lib.configuration.function.ValueHandler;
import cc.carm.lib.configuration.source.section.ConfigureSection; import cc.carm.lib.configuration.source.section.ConfigureSection;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -20,7 +21,7 @@ public class ConfigValueBuilder<V> {
} }
public @NotNull <S> SourceValueBuilder<S, V> from(@NotNull ValueType<S> sourceType) { public @NotNull <S> SourceValueBuilder<S, V> from(@NotNull ValueType<S> sourceType) {
return from(sourceType, ValueHandler.required(), ValueHandler.required()); return from(sourceType, ValueHandler.required(type), ValueHandler.required(sourceType));
} }
public @NotNull <S> SourceValueBuilder<S, V> from(@NotNull ValueType<S> sourceType, public @NotNull <S> SourceValueBuilder<S, V> from(@NotNull ValueType<S> sourceType,
@@ -30,11 +31,11 @@ public class ConfigValueBuilder<V> {
} }
public @NotNull SourceValueBuilder<String, V> fromString() { public @NotNull SourceValueBuilder<String, V> fromString() {
return from(ValueType.STRING, ValueHandler.required(), ValueHandler.stringValue()); return from(ValueType.STRING, ValueHandler.required(type), ValueHandler.stringValue());
} }
public @NotNull SectionValueBuilder<V> fromSection() { public @NotNull SectionValueBuilder<V> fromSection() {
return fromSection(ValueHandler.required(), ValueHandler.required()); return fromSection(ValueHandler.required(type), ValueHandler.required());
} }
public @NotNull SectionValueBuilder<V> fromSection( public @NotNull SectionValueBuilder<V> fromSection(
@@ -56,17 +56,24 @@ public interface ValueHandler<T, R> {
} }
@Contract(pure = true) @Contract(pure = true)
static <T> @NotNull ValueHandler<Object, T> fromObject(ValueType<T> type) { static <O, T> @NotNull ValueHandler<O, T> deserialize(ValueType<T> to) {
return (provider, input) -> provider.deserialize(type, input); return (provider, input) -> provider.deserialize(to, input);
} }
@Contract(pure = true) @Contract(pure = true)
static <T, V> @NotNull ValueHandler<T, V> required() { static <T, V> @NotNull ValueHandler<T, V> required() {
return (provider, input) -> { return (provider, input) -> {
throw new IllegalArgumentException("Please specify the value parser."); throw new IllegalArgumentException("Please specify the value parser.");
}; };
} }
@Contract(pure = true)
static <T, V> @NotNull ValueHandler<T, V> required(ValueType<V> type) {
return (provider, input) -> {
if (type.isInstance(input)) return type.cast(input); // Simple cast
throw new IllegalArgumentException("Please specify the value parser.");
};
}
} }
@@ -4,6 +4,7 @@ import cc.carm.lib.configuration.adapter.ValueAdapter;
import cc.carm.lib.configuration.adapter.ValueParser; import cc.carm.lib.configuration.adapter.ValueParser;
import cc.carm.lib.configuration.adapter.ValueSerializer; import cc.carm.lib.configuration.adapter.ValueSerializer;
import cc.carm.lib.configuration.adapter.ValueType; import cc.carm.lib.configuration.adapter.ValueType;
import cc.carm.lib.configuration.builder.map.ConfigMapCreator;
import cc.carm.lib.configuration.source.section.ConfigureSection; import cc.carm.lib.configuration.source.section.ConfigureSection;
import cc.carm.lib.configuration.value.ValueManifest; import cc.carm.lib.configuration.value.ValueManifest;
import cc.carm.lib.configuration.value.impl.CachedConfigValue; import cc.carm.lib.configuration.value.impl.CachedConfigValue;
@@ -18,12 +19,26 @@ import java.util.function.Supplier;
public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>> implements Map<K, V> { public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>> implements Map<K, V> {
public static <K, V> ConfigMapCreator<K, V> builderOf(@NotNull ValueType<K> keyType, @NotNull ValueType<V> valueType) {
return new ConfigMapCreator<>(keyType, valueType);
}
public static <K, V> ConfigMapCreator<K, V> builderOf(@NotNull Class<K> keyType, @NotNull Class<V> valueType) {
return new ConfigMapCreator<>(ValueType.of(keyType), ValueType.of(valueType));
}
public static <K, V> ConfiguredMap<K, V> of(@NotNull Supplier<? extends Map<K, V>> constructor,
@NotNull ValueAdapter<K> keyAdapter, @NotNull ValueAdapter<V> valueAdapter) {
return new ConfiguredMap<>(new ValueManifest<>(new ValueType<Map<K, V>>() {
}, constructor::get), constructor, keyAdapter, valueAdapter);
}
protected final @NotNull Supplier<? extends Map<K, V>> constructor; protected final @NotNull Supplier<? extends Map<K, V>> constructor;
protected final @NotNull ValueAdapter<K> keyAdapter; protected final @NotNull ValueAdapter<K> keyAdapter;
protected final @NotNull ValueAdapter<V> valueAdapter; protected final @NotNull ValueAdapter<V> valueAdapter;
protected ConfiguredMap(@NotNull ValueManifest<Map<K, V>> manifest, public ConfiguredMap(@NotNull ValueManifest<Map<K, V>> manifest,
@NotNull Supplier<? extends Map<K, V>> constructor, @NotNull Supplier<? extends Map<K, V>> constructor,
@NotNull ValueAdapter<K> keyAdapter, @NotNull ValueAdapter<V> valueAdapter) { @NotNull ValueAdapter<K> keyAdapter, @NotNull ValueAdapter<V> valueAdapter) {
super(manifest); super(manifest);
@@ -88,7 +103,7 @@ public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>> implements
return get().get(key); return get().get(key);
} }
public V getNotNull(Object key) { public V getNotNull(@Nullable K key) {
return Objects.requireNonNull(get(key)); return Objects.requireNonNull(get(key));
} }
@@ -49,8 +49,8 @@ public class ConfigurationTest {
System.out.println(" After size :" + DemoConfiguration.SUB.That.OPERATORS.size()); System.out.println(" After size :" + DemoConfiguration.SUB.That.OPERATORS.size());
System.out.println("> Test Section:"); System.out.println("> Test Section:");
System.out.println(DemoConfiguration.USERS.get()); System.out.println(DemoConfiguration.ALLOWLISTS.get());
DemoConfiguration.USERS.add(UserRecord.random()); DemoConfiguration.ALLOWLISTS.add(UserRecord.random());
// System.out.println("> Test Maps:"); // System.out.println("> Test Maps:");
// DemoConfiguration.USERS.forEach((k, v) -> System.out.println(k + ": " + v)); // DemoConfiguration.USERS.forEach((k, v) -> System.out.println(k + ": " + v));
@@ -6,18 +6,26 @@ import cc.carm.lib.configuration.annotation.FooterComments;
import cc.carm.lib.configuration.annotation.HeaderComments; import cc.carm.lib.configuration.annotation.HeaderComments;
import cc.carm.lib.configuration.annotation.InlineComment; import cc.carm.lib.configuration.annotation.InlineComment;
import cc.carm.lib.configuration.demo.DatabaseConfiguration; import cc.carm.lib.configuration.demo.DatabaseConfiguration;
import cc.carm.lib.configuration.demo.tests.model.ItemStack;
import cc.carm.lib.configuration.demo.tests.model.UserRecord; import cc.carm.lib.configuration.demo.tests.model.UserRecord;
import cc.carm.lib.configuration.value.ConfigValue; import cc.carm.lib.configuration.value.ConfigValue;
import cc.carm.lib.configuration.value.standard.ConfiguredList; import cc.carm.lib.configuration.value.standard.ConfiguredList;
import cc.carm.lib.configuration.value.standard.ConfiguredMap;
import cc.carm.lib.configuration.value.standard.ConfiguredValue; import cc.carm.lib.configuration.value.standard.ConfiguredValue;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
@ConfigPath(root = true) @ConfigPath(root = true)
@HeaderComments({"此处内容将显示在配置文件的最上方"}) @HeaderComments({"此处内容将显示在配置文件的最上方"})
@FooterComments({"此处内容将显示在配置文件的最下方", "可用于显示版权信息等"}) @FooterComments({
"------------------------------------------------",
"此处内容将显示在配置文件的最下方",
"可用于显示版权信息等",
"感谢您使用 https://github.com/CarmJos/EasyConfiguration !"
})
public interface DemoConfiguration extends Configuration { public interface DemoConfiguration extends Configuration {
@ConfigPath(root = true) @ConfigPath(root = true)
@@ -40,16 +48,24 @@ public interface DemoConfiguration extends Configuration {
@InlineComment("默认地注释会加到Section的首行末尾") // 通过注解给配置添加注释。 @InlineComment("默认地注释会加到Section的首行末尾") // 通过注解给配置添加注释。
@InlineComment(value = "用户名(匹配注释)", regex = "name") // 通过注解给配置添加注释。 @InlineComment(value = "用户名(匹配注释)", regex = "name") // 通过注解给配置添加注释。
@InlineComment(value = "信息", regex = "info.*") // 通过注解给配置添加注释。 @InlineComment(value = "信息", regex = "info.*") // 通过注解给配置添加注释。
ConfiguredList<UserRecord> USERS = ConfiguredList.builderOf(UserRecord.class).fromSection() ConfiguredList<UserRecord> ALLOWLISTS = ConfiguredList.builderOf(UserRecord.class).fromSection()
.parse(UserRecord::deserialize).serialize(UserRecord::serialize) .parse(UserRecord::deserialize).serialize(UserRecord::serialize)
.defaults(UserRecord.CARM).build(); .defaults(UserRecord.CARM).build();
// @HeaderComment({"[ID - UUID]对照表", "", "用于测试Map类型的解析与序列化保存"}) @HeaderComments({
// ConfiguredMap<Integer, UUID> USERS = ConfiguredMap.builderOf(Integer.class, UUID.class) "------------------------------------------------",
// .asLinkedMap().fromString() "[ID - ItemStack]对照表", "", "用于测试Map类型的解析与序列化保存"
// .parseKey(Integer::parseInt) })
// .parseValue(v -> Objects.requireNonNull(UUID.fromString(v))) @FooterComments("------------------------------------------------")
// .build(); ConfiguredMap<Integer, ItemStack> ITEMS = ConfiguredMap.builderOf(Integer.class, ItemStack.class)
.asLinkedMap().fromSection()
.parseKey(data -> Integer.parseInt(data))
.parse(ItemStack::deserialize).serialize(ItemStack::serialize)
.defaults(m -> {
m.put(1, new ItemStack("stone", 64));
m.put(2, new ItemStack("iron", 64, "铁锭", Arrays.asList("一些铁锭", "可以制造东西")));
})
.build();
/** /**
@@ -0,0 +1,78 @@
package cc.carm.lib.configuration.demo.tests.model;
import cc.carm.lib.configuration.source.section.ConfigureSection;
import org.jetbrains.annotations.Nullable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class ItemStack {
protected String material;
protected int amount;
protected @Nullable String name;
protected @Nullable List<String> lore;
public ItemStack(String material, int amount) {
this(material, amount, null, null);
}
public ItemStack(String material, int amount, @Nullable String name, @Nullable List<String> lore) {
this.material = material;
this.amount = amount;
this.name = name;
this.lore = lore;
}
public String getMaterial() {
return material;
}
public int getAmount() {
return amount;
}
public String getName() {
return name;
}
public List<String> getLore() {
return lore;
}
public void setMaterial(String material) {
this.material = material;
}
public void setAmount(int amount) {
this.amount = amount;
}
public void setName(String name) {
this.name = name;
}
public void setLore(List<String> lore) {
this.lore = lore;
}
public Map<String, Object> serialize() {
Map<String, Object> map = new LinkedHashMap<>();
map.put("material", material);
if (amount != 1) map.put("amount", amount);
if (name != null) map.put("name", name);
if (lore != null) map.put("lore", lore);
return map;
}
public static ItemStack deserialize(ConfigureSection section) {
return new ItemStack(
section.getString("material"),
section.getInt("amount", 1),
section.getString("name"),
section.getStringList("lore")
);
}
}