Relax conditions syntax via enhanced TypeAdapterFactory for Sets
This commit is contained in:
parent
bc8512e098
commit
18886c6635
|
@ -2,14 +2,10 @@
|
||||||
"conditions": [
|
"conditions": [
|
||||||
"lumi:subcategoryTest.enableLang",
|
"lumi:subcategoryTest.enableLang",
|
||||||
{
|
{
|
||||||
"not": [
|
"not": "subcategoryTest.enableLangForceDisable"
|
||||||
"subcategoryTest.enableLangForceDisable"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"fallbacks": [
|
"fallback": "assets/minecraft/lang/en_us_joke.json",
|
||||||
"assets/minecraft/lang/en_us_joke.json"
|
|
||||||
],
|
|
||||||
"expansions": {
|
"expansions": {
|
||||||
"Lights": "{lumi.subcategoryTest.enableLang}",
|
"Lights": "{lumi.subcategoryTest.enableLang}",
|
||||||
"Mode": "{lumi.debugMode}",
|
"Mode": "{lumi.debugMode}",
|
||||||
|
|
|
@ -34,9 +34,10 @@ public class RpoModInfo {
|
||||||
.registerTypeAdapter(ConfigBooleanEntry.class, new BooleanEntrySerializer())
|
.registerTypeAdapter(ConfigBooleanEntry.class, new BooleanEntrySerializer())
|
||||||
.registerTypeAdapter(ConfigBranch.class, new ConfigBranchSerializer())
|
.registerTypeAdapter(ConfigBranch.class, new ConfigBranchSerializer())
|
||||||
.registerTypeAdapter(Script.class, new ScriptDeserializer())
|
.registerTypeAdapter(Script.class, new ScriptDeserializer())
|
||||||
.registerTypeAdapter(FileRpo.class, new RpoDeserializer())
|
.registerTypeAdapter(FileRpo.class, new FileRpoDeserializer())
|
||||||
.registerTypeAdapter(DirRpo.class, new DirRpoDeserializer())
|
.registerTypeAdapter(DirRpo.class, new DirRpoDeserializer())
|
||||||
.registerTypeAdapter(Condition.class, new ConditionDeserializer())
|
.registerTypeAdapter(Condition.class, new ConditionDeserializer())
|
||||||
|
.registerTypeAdapterFactory(new SingleElementSetTypeAdapterFactory())
|
||||||
.setPrettyPrinting()
|
.setPrettyPrinting()
|
||||||
.create();
|
.create();
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -3,11 +3,11 @@ package io.gitlab.jfronny.respackopts.data;
|
||||||
import io.gitlab.jfronny.respackopts.data.condition.Condition;
|
import io.gitlab.jfronny.respackopts.data.condition.Condition;
|
||||||
import meteordevelopment.starscript.Script;
|
import meteordevelopment.starscript.Script;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class FileRpo {
|
public class FileRpo {
|
||||||
public Condition conditions;
|
public Condition conditions;
|
||||||
public List<String> fallbacks;
|
public Set<String> fallbacks;
|
||||||
public Map<String, Script> expansions;
|
public Map<String, Script> expansions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,14 +8,12 @@ import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class FileFallbackProvider {
|
public class FileFallbackProvider {
|
||||||
public static boolean fileVisible(WrappedPack pack, String name) {
|
public static boolean fileVisible(WrappedPack pack, String name) {
|
||||||
return FileRpoSearchProvider.modifyWithRpo(name, pack, rpo -> {
|
return FileRpoSearchProvider.modifyWithRpo(name, pack, rpo -> {
|
||||||
if (rpo.fallbacks != null) {
|
if (rpo.fallbacks != null) {
|
||||||
List<String> arr = rpo.fallbacks;
|
for (String s : rpo.fallbacks) {
|
||||||
for (String s : arr) {
|
|
||||||
ResourcePath tmp = new ResourcePath(s);
|
ResourcePath tmp = new ResourcePath(s);
|
||||||
if (pack.contains(tmp.getType(), tmp.getId()))
|
if (pack.contains(tmp.getType(), tmp.getId()))
|
||||||
return true;
|
return true;
|
||||||
|
@ -29,8 +27,7 @@ public class FileFallbackProvider {
|
||||||
return FileRpoSearchProvider.modifyWithRpo(name, pack, rpo -> {
|
return FileRpoSearchProvider.modifyWithRpo(name, pack, rpo -> {
|
||||||
try {
|
try {
|
||||||
if (rpo.fallbacks != null) {
|
if (rpo.fallbacks != null) {
|
||||||
List<String> arr = rpo.fallbacks;
|
for (String s : rpo.fallbacks) {
|
||||||
for (String s : arr) {
|
|
||||||
ResourcePath tmp = new ResourcePath(s);
|
ResourcePath tmp = new ResourcePath(s);
|
||||||
if (pack.contains(tmp.getType(), tmp.getId()))
|
if (pack.contains(tmp.getType(), tmp.getId()))
|
||||||
return pack.open(tmp.getType(), tmp.getId());
|
return pack.open(tmp.getType(), tmp.getId());
|
||||||
|
|
|
@ -15,19 +15,15 @@ public class DirRpoDeserializer implements JsonDeserializer<DirRpo> {
|
||||||
DirRpo rpo = new DirRpo();
|
DirRpo rpo = new DirRpo();
|
||||||
for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
|
for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
|
||||||
switch (entry.getKey()) {
|
switch (entry.getKey()) {
|
||||||
case "conditions":
|
case "conditions", "condition" -> rpo.conditions = context.deserialize(entry.getValue(), Condition.class);
|
||||||
case "condition":
|
case "fallbacks", "fallback" -> {
|
||||||
rpo.conditions = context.deserialize(entry.getValue(), Condition.class);
|
|
||||||
break;
|
|
||||||
case "fallbacks":
|
|
||||||
case "fallback":
|
|
||||||
if (entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isString()) {
|
if (entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isString()) {
|
||||||
rpo.fallback = entry.getValue().getAsString();
|
rpo.fallback = entry.getValue().getAsString();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new JsonParseException("Directory .rpos only support a single fallback");
|
throw new JsonParseException("Directory .rpos only support a single fallback");
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rpo;
|
return rpo;
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package io.gitlab.jfronny.respackopts.gson;
|
||||||
|
|
||||||
|
import com.google.gson.*;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import io.gitlab.jfronny.respackopts.data.FileRpo;
|
||||||
|
import io.gitlab.jfronny.respackopts.data.condition.Condition;
|
||||||
|
import meteordevelopment.starscript.Script;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class FileRpoDeserializer implements JsonDeserializer<FileRpo> {
|
||||||
|
private static final Type stringScriptMapType = new TypeToken<Map<String, Script>>(){}.getType();
|
||||||
|
private static final Type stringSetType = new TypeToken<Set<String>>(){}.getType();
|
||||||
|
@Override
|
||||||
|
public FileRpo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
if (!json.isJsonObject())
|
||||||
|
throw new JsonParseException("Rpo must be a json object");
|
||||||
|
FileRpo rpo = new FileRpo();
|
||||||
|
for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
|
||||||
|
switch (entry.getKey()) {
|
||||||
|
case "conditions", "condition" -> rpo.conditions = context.deserialize(entry.getValue(), Condition.class);
|
||||||
|
case "fallbacks", "fallback" -> rpo.fallbacks = context.deserialize(entry.getValue(), stringSetType);
|
||||||
|
case "expansions", "expansion" -> rpo.expansions = context.deserialize(entry.getValue(), stringScriptMapType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rpo;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,46 +0,0 @@
|
||||||
package io.gitlab.jfronny.respackopts.gson;
|
|
||||||
|
|
||||||
import com.google.gson.*;
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
|
||||||
import io.gitlab.jfronny.respackopts.data.FileRpo;
|
|
||||||
import io.gitlab.jfronny.respackopts.data.condition.Condition;
|
|
||||||
import meteordevelopment.starscript.Script;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class RpoDeserializer implements JsonDeserializer<FileRpo> {
|
|
||||||
@Override
|
|
||||||
public FileRpo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
|
||||||
if (!json.isJsonObject())
|
|
||||||
throw new JsonParseException("Rpo must be a json object");
|
|
||||||
FileRpo rpo = new FileRpo();
|
|
||||||
for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
|
|
||||||
switch (entry.getKey()) {
|
|
||||||
case "conditions":
|
|
||||||
case "condition":
|
|
||||||
rpo.conditions = context.deserialize(entry.getValue(), Condition.class);
|
|
||||||
break;
|
|
||||||
case "fallbacks":
|
|
||||||
case "fallback":
|
|
||||||
if (entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isString()) {
|
|
||||||
rpo.fallbacks = new ArrayList<>();
|
|
||||||
rpo.fallbacks.add(entry.getValue().getAsString());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Type listType = new TypeToken<List<String>>(){}.getType();
|
|
||||||
rpo.fallbacks = context.deserialize(entry.getValue(), listType);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "expansions":
|
|
||||||
case "expansion":
|
|
||||||
Type listType = new TypeToken<Map<String, Script>>(){}.getType();
|
|
||||||
rpo.expansions = context.deserialize(entry.getValue(), listType);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rpo;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
package io.gitlab.jfronny.respackopts.gson;
|
||||||
|
|
||||||
|
import com.google.gson.*;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonToken;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
import io.gitlab.jfronny.respackopts.RpoModInfo;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class SingleElementSetTypeAdapterFactory implements TypeAdapterFactory {
|
||||||
|
@Override
|
||||||
|
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
|
||||||
|
Type type = typeToken.getType();
|
||||||
|
if (typeToken.getRawType() != Set.class
|
||||||
|
|| !(type instanceof ParameterizedType pt))
|
||||||
|
return null;
|
||||||
|
if (RpoModInfo.CONFIG.debugLogs)
|
||||||
|
RpoModInfo.LOGGER.info("Using SingleElementSetTypeAdapter for " + typeToken.toString());
|
||||||
|
Type elementType = pt.getActualTypeArguments()[0];
|
||||||
|
TypeAdapter<?> elementAdapter = gson.getAdapter(TypeToken.get(elementType));
|
||||||
|
return (TypeAdapter<T>) createAdapter(elementAdapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> TypeAdapter<Set<T>> createAdapter(final TypeAdapter<T> elementAdapter) {
|
||||||
|
return new TypeAdapter<>() {
|
||||||
|
@Override
|
||||||
|
public void write(JsonWriter out, Set<T> value) throws IOException {
|
||||||
|
if (value == null) {
|
||||||
|
out.nullValue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.beginArray();
|
||||||
|
for (T entry : value) {
|
||||||
|
elementAdapter.write(out, entry);
|
||||||
|
}
|
||||||
|
out.endArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<T> read(JsonReader in) throws IOException {
|
||||||
|
if (in.peek() == JsonToken.NULL) {
|
||||||
|
in.nextNull();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<T> list = new LinkedHashSet<>();
|
||||||
|
if (in.peek() == JsonToken.BEGIN_ARRAY) {
|
||||||
|
in.beginArray();
|
||||||
|
while (in.hasNext()) {
|
||||||
|
list.add(elementAdapter.read(in));
|
||||||
|
}
|
||||||
|
in.endArray();
|
||||||
|
}
|
||||||
|
else list.add(elementAdapter.read(in));
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
package io.gitlab.jfronny.respackopts;
|
package io.gitlab.jfronny.respackopts;
|
||||||
|
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import io.gitlab.jfronny.respackopts.data.ConfigFile;
|
||||||
import io.gitlab.jfronny.respackopts.data.entry.*;
|
import io.gitlab.jfronny.respackopts.data.entry.*;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
@ -8,6 +10,7 @@ import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import static io.gitlab.jfronny.respackopts.Respackopts.*;
|
import static io.gitlab.jfronny.respackopts.Respackopts.*;
|
||||||
import static io.gitlab.jfronny.respackopts.RpoModInfo.*;
|
import static io.gitlab.jfronny.respackopts.RpoModInfo.*;
|
||||||
|
@ -22,6 +25,7 @@ class RespackoptsTest {
|
||||||
static void initialize() {
|
static void initialize() {
|
||||||
LOGGER.info("Expected error end");
|
LOGGER.info("Expected error end");
|
||||||
CONF_DIR = Paths.get("./test");
|
CONF_DIR = Paths.get("./test");
|
||||||
|
CONFIG = new ConfigFile();
|
||||||
assertDoesNotThrow(() -> Files.deleteIfExists(CONF_DIR.resolve(testEntry1Name + ".json")));
|
assertDoesNotThrow(() -> Files.deleteIfExists(CONF_DIR.resolve(testEntry1Name + ".json")));
|
||||||
assertDoesNotThrow(() -> Files.createDirectories(CONF_DIR));
|
assertDoesNotThrow(() -> Files.createDirectories(CONF_DIR));
|
||||||
SAVE_ACTIONS.add(() -> LOGGER.info("Save"));
|
SAVE_ACTIONS.add(() -> LOGGER.info("Save"));
|
||||||
|
@ -94,4 +98,25 @@ class RespackoptsTest {
|
||||||
cbNew.add(testEntryName, new ConfigBooleanEntry(true));
|
cbNew.add(testEntryName, new ConfigBooleanEntry(true));
|
||||||
cbNew.sync(cb, SyncMode.RESPACK_LOAD);
|
cbNew.sync(cb, SyncMode.RESPACK_LOAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void gsonSetOrder() {
|
||||||
|
String[] expected = new String[] {"one", "two", "three", "zero", "76"};
|
||||||
|
String gson = "[\"one\", \"two\", \"three\", \"zero\", \"76\"]";
|
||||||
|
Set<String> parsed = GSON.fromJson(gson, new TypeToken<Set<String>>(){}.getType());
|
||||||
|
int i = 0;
|
||||||
|
for (String s : parsed) {
|
||||||
|
assertEquals(s, expected[i++]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void gsonSingleEntrySet() {
|
||||||
|
String gson = "\"someText\"";
|
||||||
|
Set<String> parsed = GSON.fromJson(gson, new TypeToken<Set<String>>(){}.getType());
|
||||||
|
assertEquals(parsed.size(), 1);
|
||||||
|
for (String s : parsed) {
|
||||||
|
assertEquals(s, "someText");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user