Inceptum/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/gson/ModSourceAdapter.java

97 lines
4.2 KiB
Java

package io.gitlab.jfronny.inceptum.launcher.gson;
import io.gitlab.jfronny.gson.JsonParseException;
import io.gitlab.jfronny.gson.stream.JsonReader;
import io.gitlab.jfronny.gson.stream.JsonWriter;
import io.gitlab.jfronny.inceptum.launcher.system.source.*;
import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.Set;
public class ModSourceAdapter {
public static void write(ModSource src, JsonWriter writer) throws IOException {
writer.beginObject();
if (src instanceof ModrinthModSource mo) {
writer.name("type").value("modrinth")
.name("id").value(mo.versionId);
} else if (src instanceof DirectModSource di) {
writer.name("type").value("direct")
.name("fileName").value(di.fileName)
.name("url").value(di.url)
.name("dependencies");
writer.beginArray();
for (ModSource dependency : di.dependencies) {
write(dependency, writer);
}
writer.endArray();
} else if (src instanceof CurseforgeModSource cu) {
writer.name("type").value("curseforge");
if (cu.shortName.matches("\\d+")) {
writer.name("projectId").value(cu.projectId);
} else {
writer.name("project").value(cu.shortName);
}
writer.name("fileId").value(cu.fileId);
} else throw new RuntimeException("ModSources with the type " + src.getClass() + " are not supported");
writer.endObject();
}
public static ModSource read(JsonReader reader) throws IOException {
String type = null;
String mr$id = null;
Integer cf$projectId = null;
String cf$project = null;
Integer cf$fileId = null;
String direct$fileName = null;
String direct$url = null;
Set<ModSource> direct$dependencies = null;
reader.beginObject();
while (reader.hasNext()) {
switch (reader.nextName()) {
case "type" -> type = reader.nextString();
case "id" -> mr$id = reader.nextString();
case "projectId" -> cf$projectId = reader.nextInt();
case "project" -> cf$project = reader.nextString();
case "fileId" -> cf$fileId = reader.nextInt();
case "fileName" -> direct$fileName = reader.nextString();
case "url" -> direct$url = reader.nextString();
case "dependencies" -> {
direct$dependencies = new LinkedHashSet<>();
reader.beginArray();
while (reader.hasNext()) direct$dependencies.add(read(reader));
reader.endArray();
}
}
}
reader.endObject();
if (type == null) throw new JsonParseException("Expected ModSource to contain a type");
return switch (type) {
case "modrinth" -> {
if (mr$id == null) throw new JsonParseException("Expected ModrinthModSource to contain a version ID");
yield new ModrinthModSource(mr$id);
}
case "curseforge" -> {
if (cf$fileId == null)
throw new JsonParseException("Expected a fileId in this curseforge project");
if (cf$projectId != null) yield new CurseforgeModSource(cf$projectId, cf$fileId);
else if (cf$project != null) yield new CurseforgeModSource(cf$project, cf$fileId);
else throw new JsonParseException("Expected a projectId in this curseforge project");
}
case "direct" -> {
if (direct$fileName == null) throw new JsonParseException("Expected direct download to have a fileName");
if (direct$url == null) throw new JsonParseException("Expected direct download to have a url");
if (direct$dependencies == null) yield new DirectModSource(direct$fileName, direct$url, Set.of());
else {
yield new DirectModSource(direct$fileName, direct$url, direct$dependencies);
}
}
default -> throw new JsonParseException("Unexpected ModSource type: " + type);
};
}
}