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