From ed8eb00566a5e3b7f2d5564d7977a4b3ec8fe5b3 Mon Sep 17 00:00:00 2001 From: Linnea Gräf Date: Thu, 14 Nov 2024 01:35:24 +0100 Subject: wip --- genrecord.ts | 0 gentuples.ts | 80 ++ .../src/main/java/moe/nea/jcp/gson/GsonCodecs.java | 10 + .../java/moe/nea/jcp/gson/GsonListBuilder.java | 27 + .../main/java/moe/nea/jcp/gson/GsonListView.java | 21 + .../main/java/moe/nea/jcp/gson/GsonOperations.java | 63 +- .../java/moe/nea/jcp/gson/GsonRecordBuilder.java | 47 + .../main/java/moe/nea/jcp/gson/GsonRecordView.java | 24 + src/main/java/moe/nea/pcj/AppendableError.java | 21 - src/main/java/moe/nea/pcj/Codec.java | 3 +- src/main/java/moe/nea/pcj/Decode.java | 4 +- src/main/java/moe/nea/pcj/Encode.java | 4 +- src/main/java/moe/nea/pcj/JsonLikeError.java | 29 - src/main/java/moe/nea/pcj/JsonLikeOperations.java | 28 - src/main/java/moe/nea/pcj/ListBuilder.java | 9 - src/main/java/moe/nea/pcj/ListView.java | 14 - src/main/java/moe/nea/pcj/RecordBuilder.java | 6 - src/main/java/moe/nea/pcj/RecordView.java | 10 - src/main/java/moe/nea/pcj/Result.java | 78 +- src/main/java/moe/nea/pcj/Tuple.java | 1028 +++++++++++++++++++- src/main/java/moe/nea/pcj/json/AtField.java | 4 + src/main/java/moe/nea/pcj/json/BasicCodecs.java | 51 + .../java/moe/nea/pcj/json/DuplicateJsonKey.java | 4 + src/main/java/moe/nea/pcj/json/JsonCodec.java | 31 + src/main/java/moe/nea/pcj/json/JsonLikeError.java | 4 + .../java/moe/nea/pcj/json/JsonLikeOperations.java | 32 + src/main/java/moe/nea/pcj/json/ListBuilder.java | 9 + src/main/java/moe/nea/pcj/json/ListView.java | 14 + src/main/java/moe/nea/pcj/json/MapCodec.java | 17 + src/main/java/moe/nea/pcj/json/MissingKey.java | 4 + src/main/java/moe/nea/pcj/json/RecordBuilder.java | 12 + src/main/java/moe/nea/pcj/json/RecordCodec.java | 59 ++ src/main/java/moe/nea/pcj/json/RecordView.java | 10 + .../moe/nea/pcj/json/UnexpectedJsonElement.java | 7 + src/main/java/moe/nea/pcj/json/package-info.java | 4 + 35 files changed, 1590 insertions(+), 178 deletions(-) create mode 100644 genrecord.ts create mode 100755 gentuples.ts create mode 100644 gson/src/main/java/moe/nea/jcp/gson/GsonCodecs.java create mode 100644 gson/src/main/java/moe/nea/jcp/gson/GsonListBuilder.java create mode 100644 gson/src/main/java/moe/nea/jcp/gson/GsonListView.java create mode 100644 gson/src/main/java/moe/nea/jcp/gson/GsonRecordBuilder.java create mode 100644 gson/src/main/java/moe/nea/jcp/gson/GsonRecordView.java delete mode 100644 src/main/java/moe/nea/pcj/AppendableError.java delete mode 100644 src/main/java/moe/nea/pcj/JsonLikeError.java delete mode 100644 src/main/java/moe/nea/pcj/JsonLikeOperations.java delete mode 100644 src/main/java/moe/nea/pcj/ListBuilder.java delete mode 100644 src/main/java/moe/nea/pcj/ListView.java delete mode 100644 src/main/java/moe/nea/pcj/RecordBuilder.java delete mode 100644 src/main/java/moe/nea/pcj/RecordView.java create mode 100644 src/main/java/moe/nea/pcj/json/AtField.java create mode 100644 src/main/java/moe/nea/pcj/json/BasicCodecs.java create mode 100644 src/main/java/moe/nea/pcj/json/DuplicateJsonKey.java create mode 100644 src/main/java/moe/nea/pcj/json/JsonCodec.java create mode 100644 src/main/java/moe/nea/pcj/json/JsonLikeError.java create mode 100644 src/main/java/moe/nea/pcj/json/JsonLikeOperations.java create mode 100644 src/main/java/moe/nea/pcj/json/ListBuilder.java create mode 100644 src/main/java/moe/nea/pcj/json/ListView.java create mode 100644 src/main/java/moe/nea/pcj/json/MapCodec.java create mode 100644 src/main/java/moe/nea/pcj/json/MissingKey.java create mode 100644 src/main/java/moe/nea/pcj/json/RecordBuilder.java create mode 100644 src/main/java/moe/nea/pcj/json/RecordCodec.java create mode 100644 src/main/java/moe/nea/pcj/json/RecordView.java create mode 100644 src/main/java/moe/nea/pcj/json/UnexpectedJsonElement.java create mode 100644 src/main/java/moe/nea/pcj/json/package-info.java diff --git a/genrecord.ts b/genrecord.ts new file mode 100644 index 0000000..e69de29 diff --git a/gentuples.ts b/gentuples.ts new file mode 100755 index 0000000..ba74c29 --- /dev/null +++ b/gentuples.ts @@ -0,0 +1,80 @@ +#!/usr/bin/env node --experimental-strip-types + +function nameFor(va: string): string { + return va.replace("E", "T").replace("T", "element") +} + +function typArgs(a: string[]): string { + if (a.length == 0) return "" + return "<" + a.join(", ") + ">" +} + +function genFunc(elementNumber: number, max: number) { + console.log("\t@FunctionalInterface") + const vars: string[] = [...new Array(elementNumber)].map((_, idx) => `T${idx}`) + console.log(`\tinterface Func${elementNumber}${typArgs(['R', ...vars])} {`) + console.log(`\t\tR apply(${vars.map(it => it + " " + it.replace("T", "arg")).join(", ")});`) + console.log("\t}") +} + +function genTuple(elementNumber: number, max: number) { + const vars: string[] = [...new Array(elementNumber)].map((_, idx) => `T${idx}`) + if (elementNumber == 0) { + console.log("\tclass Tuple0 implements Tuple {") + } else { + console.log(`\trecord Tuple${elementNumber}${typArgs(vars)}(${vars.map(it => it + " " + nameFor(it)).join(", ")}) {`) + } + console.log(`\t\tpublic R applyTo(Func${elementNumber}${typArgs(['R', ...vars])} func) {`) + console.log(`\t\t\treturn func.apply(${vars.map(it => "this." + nameFor(it)).join(", ")});`) + console.log("\t\t}") + console.log(`\t\tpublic static ${typArgs(['R', ...vars])} Result collect(` + + `Tuple${elementNumber}${typArgs(vars.map(it => `Result<${it}, R>`))} tuple` + + `) {`) + console.log("\t\t\treturn") + for (const tVar of vars) { + console.log(`\t\t\t\ttuple.${nameFor(tVar)}.flatMap(${nameFor(tVar)} ->`) + } + console.log(`\t\t\t\t\tResult.ok(new Tuple${elementNumber}${elementNumber ? '<>' : ''}(${vars.map(it => nameFor(it)).join(", ")}))`) + for (const tVar of vars) { + console.log(`\t\t\t\t)`) + } + console.log("\t\t\t;") + console.log("\t\t}") + + + const newVars = vars.map(it => it.replace("T", "E")) + console.log(`\t\tpublic ${typArgs(newVars)} Tuple${elementNumber}${typArgs(newVars)} map(` + + newVars.map(it => `Func1<${it}, ${it.replace("E", "T")}> ${it.replace("E", "map")}`).join(", ") + + `) {`) + console.log(`\t\t\treturn new Tuple${elementNumber}${(elementNumber ? '<>' : '')}(${newVars.map(it => `${it.replace("E", "map")}.apply(this.${nameFor(it)})`).join(", ")});`) + console.log("\t\t}") + + for (let extraElements = 0; extraElements < (max - elementNumber); extraElements++) { + const extraVars = [...new Array(extraElements)].map((_, idx) => `E${idx}`) + const sumElements = extraElements + elementNumber; + console.log(`\t\tpublic ${typArgs(extraVars)} Tuple${sumElements}${typArgs([...vars, ...extraVars])} ` + + `join(Tuple${extraElements}${typArgs(extraVars)} other) {`) + console.log(`\t\t\treturn new Tuple${sumElements}${sumElements ? '<>' : ''}(${[ + ...vars.map(it => "this." + nameFor(it)), + ...extraVars.map(it => "other." + nameFor(it))].join(", ")});`) + console.log("\t\t}") + } + console.log("\t}") +} + + +function genTuples(maxI: number) { + console.log("// @gen" + "erated by gentuples.ts") + console.log("package moe.nea.pcj;") + console.log() + console.log("@SuppressWarnings(\"unused\")") + console.log("public interface Tuple {") + for (let i = 0; i < maxI; i++) { + genTuple(i, maxI); + genFunc(i, maxI) + } + console.log("}") +} + +genTuples(15) + diff --git a/gson/src/main/java/moe/nea/jcp/gson/GsonCodecs.java b/gson/src/main/java/moe/nea/jcp/gson/GsonCodecs.java new file mode 100644 index 0000000..616d713 --- /dev/null +++ b/gson/src/main/java/moe/nea/jcp/gson/GsonCodecs.java @@ -0,0 +1,10 @@ +package moe.nea.jcp.gson; + +import com.google.gson.JsonElement; +import moe.nea.pcj.json.BasicCodecs; + +public class GsonCodecs extends BasicCodecs { + protected GsonCodecs() {} + + public static final GsonCodecs INSTANCE = new GsonCodecs(); +} diff --git a/gson/src/main/java/moe/nea/jcp/gson/GsonListBuilder.java b/gson/src/main/java/moe/nea/jcp/gson/GsonListBuilder.java new file mode 100644 index 0000000..d1a6302 --- /dev/null +++ b/gson/src/main/java/moe/nea/jcp/gson/GsonListBuilder.java @@ -0,0 +1,27 @@ +package moe.nea.jcp.gson; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import moe.nea.pcj.json.ListBuilder; + +public class GsonListBuilder extends GsonListView implements ListBuilder { + + public GsonListBuilder() { + super(new JsonArray()); + } + + @Override + public JsonArray complete() { + return jsonArray; + } + + @Override + public void add(JsonElement value) { + jsonArray.add(value); + } + + @Override + public void set(int index, JsonElement value) { + jsonArray.set(index, value); + } +} diff --git a/gson/src/main/java/moe/nea/jcp/gson/GsonListView.java b/gson/src/main/java/moe/nea/jcp/gson/GsonListView.java new file mode 100644 index 0000000..2a0dcf5 --- /dev/null +++ b/gson/src/main/java/moe/nea/jcp/gson/GsonListView.java @@ -0,0 +1,21 @@ +package moe.nea.jcp.gson; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import moe.nea.pcj.json.ListView; + +public class GsonListView implements ListView { + final JsonArray jsonArray; + + public GsonListView(JsonArray jsonArray) {this.jsonArray = jsonArray;} + + @Override + public int length() { + return jsonArray.size(); + } + + @Override + public JsonElement getUnsafe(int index) { + return jsonArray.get(index); + } +} diff --git a/gson/src/main/java/moe/nea/jcp/gson/GsonOperations.java b/gson/src/main/java/moe/nea/jcp/gson/GsonOperations.java index 7d81b9f..7957d05 100644 --- a/gson/src/main/java/moe/nea/jcp/gson/GsonOperations.java +++ b/gson/src/main/java/moe/nea/jcp/gson/GsonOperations.java @@ -1,15 +1,19 @@ package moe.nea.jcp.gson; +import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonNull; -import moe.nea.pcj.JsonLikeError; -import moe.nea.pcj.JsonLikeOperations; -import moe.nea.pcj.ListBuilder; -import moe.nea.pcj.ListView; -import moe.nea.pcj.RecordBuilder; -import moe.nea.pcj.RecordView; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import moe.nea.pcj.json.JsonLikeError; +import moe.nea.pcj.json.JsonLikeOperations; +import moe.nea.pcj.json.ListBuilder; +import moe.nea.pcj.json.ListView; +import moe.nea.pcj.json.RecordBuilder; +import moe.nea.pcj.json.RecordView; import moe.nea.pcj.Result; import moe.nea.pcj.Unit; +import moe.nea.pcj.json.UnexpectedJsonElement; public class GsonOperations implements JsonLikeOperations { @Override @@ -20,56 +24,71 @@ public class GsonOperations implements JsonLikeOperations { @Override public Result getNull(JsonElement element) { if (element.isJsonNull()) return Result.ok(Unit.INSTANCE); - return Result.fail(); + return Result.fail(new UnexpectedJsonElement("null", element)); } @Override public JsonElement createNumeric(Number value) { - return null; + return new JsonPrimitive(value); } @Override - public Result getInt(JsonElement element) { - return null; + public Result getNumeric(JsonElement element) { + if (element instanceof JsonPrimitive primitive && primitive.isNumber()) { + return Result.ok(primitive.getAsNumber()); + } + return Result.fail(new UnexpectedJsonElement("number", element)); } @Override public JsonElement createString(String value) { - return null; + return new JsonPrimitive(value); } @Override public Result getString(JsonElement element) { - return null; + if (element instanceof JsonPrimitive primitive && primitive.isString()) { + return Result.ok(primitive.getAsString()); + } + return Result.fail(new UnexpectedJsonElement("string", element)); } @Override public JsonElement createBoolean(boolean value) { - return null; + return new JsonPrimitive(value); } @Override public Result getBoolean(JsonElement jsonElement) { - return null; + if (jsonElement instanceof JsonPrimitive primitive && primitive.isBoolean()) { + return Result.ok(primitive.getAsBoolean()); + } + return Result.fail(new UnexpectedJsonElement("boolean", jsonElement)); } @Override - public RecordBuilder createObject() { - return null; + public RecordBuilder createObject() { + return new GsonRecordBuilder(); } @Override - public Result, ? extends JsonLikeError> getObject(JsonElement jsonElement) { - return null; + public Result, ? extends JsonLikeError> getObject(JsonElement jsonElement) { + if (jsonElement instanceof JsonObject object) { + return Result.ok(new GsonRecordView(object)); + } + return Result.fail(new UnexpectedJsonElement("object", jsonElement)); } @Override - public ListBuilder createList() { - return null; + public ListBuilder createList() { + return new GsonListBuilder(); } @Override - public Result, ? extends JsonLikeError> getList(JsonElement jsonElement) { - return null; + public Result, ? extends JsonLikeError> getList(JsonElement jsonElement) { + if (jsonElement instanceof JsonArray array) { + return Result.ok(new GsonListView(array)); + } + return Result.fail(new UnexpectedJsonElement("list", jsonElement)); } } diff --git a/gson/src/main/java/moe/nea/jcp/gson/GsonRecordBuilder.java b/gson/src/main/java/moe/nea/jcp/gson/GsonRecordBuilder.java new file mode 100644 index 0000000..ded1953 --- /dev/null +++ b/gson/src/main/java/moe/nea/jcp/gson/GsonRecordBuilder.java @@ -0,0 +1,47 @@ +package moe.nea.jcp.gson; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import moe.nea.pcj.Result; +import moe.nea.pcj.Unit; +import moe.nea.pcj.json.DuplicateJsonKey; +import moe.nea.pcj.json.JsonLikeError; +import moe.nea.pcj.json.RecordBuilder; + +import java.util.stream.Stream; + +public class GsonRecordBuilder extends GsonRecordView implements RecordBuilder { + public GsonRecordBuilder() { + super(new JsonObject()); + } + + boolean completed = false; + + @Override + public Result, JsonLikeError> mergeWith(RecordBuilder other) { + var next = new GsonRecordBuilder(); + return Result.cast(Stream.of(this.complete(), other.complete()) + .flatMap(it -> ((JsonObject) it).entrySet().stream()) + .map(it -> next.add(it.getKey(), it.getValue())) + .reduce((left, right) -> left.appendErrors(right.errors())) + .map(it -> it.map(unit -> next)) + .orElse(Result.ok(next))); + } + + @Override + public Result add(String key, JsonElement value) { + if (completed) throw new IllegalStateException("JsonObject already completed"); + if (jsonObject.has(key)) + return Result.fail(new DuplicateJsonKey(key)); + jsonObject.add(key, value); + return Result.ok(Unit.INSTANCE); + } + + @Override + public JsonObject complete() { + if (completed) + throw new IllegalStateException("JsonObject already completed"); + completed = true; + return jsonObject; + } +} diff --git a/gson/src/main/java/moe/nea/jcp/gson/GsonRecordView.java b/gson/src/main/java/moe/nea/jcp/gson/GsonRecordView.java new file mode 100644 index 0000000..b20d0a7 --- /dev/null +++ b/gson/src/main/java/moe/nea/jcp/gson/GsonRecordView.java @@ -0,0 +1,24 @@ +package moe.nea.jcp.gson; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import moe.nea.pcj.json.RecordView; + +import java.util.Collection; +import java.util.Optional; + +public class GsonRecordView implements RecordView { + final JsonObject jsonObject; + + public GsonRecordView(JsonObject jsonObject) {this.jsonObject = jsonObject;} + + @Override + public Collection getKeys() { + return jsonObject.keySet(); + } + + @Override + public Optional get(String key) { + return Optional.ofNullable(jsonObject.get(key)); + } +} diff --git a/src/main/java/moe/nea/pcj/AppendableError.java b/src/main/java/moe/nea/pcj/AppendableError.java deleted file mode 100644 index 6ec48fa..0000000 --- a/src/main/java/moe/nea/pcj/AppendableError.java +++ /dev/null @@ -1,21 +0,0 @@ -package moe.nea.pcj; - -import java.util.List; -import java.util.Optional; - -public interface AppendableError> { - /** - * @return an optional Self with getSuppressed containing the argument - */ - Optional appendError(Object other); - - List getSuppressed(); - - static T concatError(T left, T right) { - if (left instanceof AppendableError appendable) { - var opt = (Optional) appendable.appendError(right); - return opt.orElse(left); - } - return left; - } -} diff --git a/src/main/java/moe/nea/pcj/Codec.java b/src/main/java/moe/nea/pcj/Codec.java index 728fbc6..121e05f 100644 --- a/src/main/java/moe/nea/pcj/Codec.java +++ b/src/main/java/moe/nea/pcj/Codec.java @@ -1,5 +1,6 @@ package moe.nea.pcj; -public interface Codec extends Decode, Encode { +public interface Codec, DeErr, CoErr> + extends Decode, Encode { } diff --git a/src/main/java/moe/nea/pcj/Decode.java b/src/main/java/moe/nea/pcj/Decode.java index a335849..d10c98a 100644 --- a/src/main/java/moe/nea/pcj/Decode.java +++ b/src/main/java/moe/nea/pcj/Decode.java @@ -1,5 +1,5 @@ package moe.nea.pcj; -public interface Decode { - Result decode(Format format, Operation op); +public interface Decode, Err> { + Result decode(Format format, Op ops); } diff --git a/src/main/java/moe/nea/pcj/Encode.java b/src/main/java/moe/nea/pcj/Encode.java index 0c17097..834ce66 100644 --- a/src/main/java/moe/nea/pcj/Encode.java +++ b/src/main/java/moe/nea/pcj/Encode.java @@ -1,5 +1,5 @@ package moe.nea.pcj; -public interface Encode { - Result encode(Typ data, Operation op); +public interface Encode, Err> { + Result encode(Typ data, Op ops); } diff --git a/src/main/java/moe/nea/pcj/JsonLikeError.java b/src/main/java/moe/nea/pcj/JsonLikeError.java deleted file mode 100644 index 6d309ab..0000000 --- a/src/main/java/moe/nea/pcj/JsonLikeError.java +++ /dev/null @@ -1,29 +0,0 @@ -package moe.nea.pcj; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -public abstract class JsonLikeError> implements AppendableError> { - private final List> suppressed = new ArrayList<>(); - - protected abstract Self copySelfWithoutSuppressions(); - - @Override - public List> getSuppressed() { - return Collections.unmodifiableList(suppressed); - } - - @Override - public Optional> appendError(Object other) { - if (other instanceof JsonLikeError jsonLikeOther) { - var newSelf = (JsonLikeError) copySelfWithoutSuppressions(); - newSelf.suppressed.add(jsonLikeOther.copySelfWithoutSuppressions()); - newSelf.suppressed.addAll(jsonLikeOther.getSuppressed()); - return Optional.of(newSelf); - } else { - return Optional.empty(); - } - } -} diff --git a/src/main/java/moe/nea/pcj/JsonLikeOperations.java b/src/main/java/moe/nea/pcj/JsonLikeOperations.java deleted file mode 100644 index 2188568..0000000 --- a/src/main/java/moe/nea/pcj/JsonLikeOperations.java +++ /dev/null @@ -1,28 +0,0 @@ -package moe.nea.pcj; - -public interface JsonLikeOperations extends Operation { - - Format createNull(Unit value); - - Result getNull(Format element); - - Format createNumeric(Number value); - - Result getInt(Format element); - - Format createString(String value); - - Result getString(Format element); - - Format createBoolean(boolean value); - - Result getBoolean(Format format); - - RecordBuilder createObject(); - - Result, ? extends JsonLikeError> getObject(Format format); - - ListBuilder createList(); - - Result, ? extends JsonLikeError> getList(Format format); -} diff --git a/src/main/java/moe/nea/pcj/ListBuilder.java b/src/main/java/moe/nea/pcj/ListBuilder.java deleted file mode 100644 index 9f6e9a3..0000000 --- a/src/main/java/moe/nea/pcj/ListBuilder.java +++ /dev/null @@ -1,9 +0,0 @@ -package moe.nea.pcj; - -public interface ListBuilder extends ListView { - Format complete(); - - void add(ElementFormat value); - - void set(int index, ElementFormat value); -} diff --git a/src/main/java/moe/nea/pcj/ListView.java b/src/main/java/moe/nea/pcj/ListView.java deleted file mode 100644 index 57c229a..0000000 --- a/src/main/java/moe/nea/pcj/ListView.java +++ /dev/null @@ -1,14 +0,0 @@ -package moe.nea.pcj; - -import java.util.Optional; - -public interface ListView { - int length(); - - default Optional getSafe(int index) { - if (index < 0 || index >= length()) return Optional.empty(); - return Optional.of(getUnsafe(index)); - } - - Format getUnsafe(int index); -} diff --git a/src/main/java/moe/nea/pcj/RecordBuilder.java b/src/main/java/moe/nea/pcj/RecordBuilder.java deleted file mode 100644 index c28be7b..0000000 --- a/src/main/java/moe/nea/pcj/RecordBuilder.java +++ /dev/null @@ -1,6 +0,0 @@ -package moe.nea.pcj; - -public interface RecordBuilder extends RecordView { - void add(String key, ElementFormat value); // TODO - Format complete(); -} diff --git a/src/main/java/moe/nea/pcj/RecordView.java b/src/main/java/moe/nea/pcj/RecordView.java deleted file mode 100644 index 84057ba..0000000 --- a/src/main/java/moe/nea/pcj/RecordView.java +++ /dev/null @@ -1,10 +0,0 @@ -package moe.nea.pcj; - -import java.util.Collection; -import java.util.Optional; - -public interface RecordView { - Collection getKeys(); - - Optional get(String key); -} diff --git a/src/main/java/moe/nea/pcj/Result.java b/src/main/java/moe/nea/pcj/Result.java index 8bec96a..e43633b 100644 --- a/src/main/java/moe/nea/pcj/Result.java +++ b/src/main/java/moe/nea/pcj/Result.java @@ -2,12 +2,15 @@ package moe.nea.pcj; import org.jspecify.annotations.Nullable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Optional; import java.util.function.Function; public sealed interface Result permits Result.Ok, Result.Fail { default boolean isOk() { - return error().isEmpty(); + return errors().isEmpty(); } Optional value(); @@ -18,26 +21,31 @@ public sealed interface Result permits Result.Ok, Result.Fail { return value().or(this::partial); } - Optional error(); + List errors(); default Result map(Function mapper) { return flatMap(mapper.andThen(Result::ok)); } - default Result flatMap(Function> mapper) { - return flatMapBoth(mapper, Result::fail); + Result flatMap(Function> mapper); + + default Result mapError(Function mapper) { + return mapErrors(it -> it.stream().map(mapper).toList()); } - Result flatMapBoth( - Function> mapGood, - Function> mapBad); + Result mapErrors(Function, List> mapper); - Result appendError(Bad error); + Result appendErrors(List error); record Ok(Good okValue) implements Result { @Override - public Result appendError(Bad error) { - return Result.partial(okValue, error); + public Result appendErrors(List errors) { + return new Fail<>(okValue, errors); + } + + @Override + public Result mapErrors(Function, List> mapper) { + return new Ok<>(okValue); } @Override @@ -46,22 +54,26 @@ public sealed interface Result permits Result.Ok, Result.Fail { } @Override - public Optional value() { - return Optional.of(okValue); + public List errors() { + return List.of(); } @Override - public Optional error() { - return Optional.empty(); + public Result flatMap(Function> mapper) { + return Result.cast(mapper.apply(okValue)); } @Override - public Result flatMapBoth(Function> mapGood, Function> mapBad) { - return mapGood.apply(okValue); + public Optional value() { + return Optional.of(okValue); } } - record Fail(@Nullable Good partialValue, Bad badValue) implements Result { + record Fail(@Nullable Good partialValue, List badValue) implements Result { + public Fail { + if (badValue.isEmpty()) + throw new IllegalArgumentException("Cannot create failure without any error values"); + } @Override public Optional value() { @@ -74,22 +86,28 @@ public sealed interface Result permits Result.Ok, Result.Fail { } @Override - public Optional error() { - return Optional.of(badValue); + public List errors() { + return Collections.unmodifiableList(badValue); } @Override - public Result flatMapBoth(Function> mapGood, Function> mapBad) { + public Result flatMap(Function> mapper) { if (partialValue != null) { - var nextPartial = mapGood.apply(partialValue); - return nextPartial.appendError(badValue); + return Result.cast(mapper.apply(partialValue)).appendErrors(badValue); } - return mapBad.apply(badValue); + return new Fail<>(null, badValue); + } + + @Override + public Result mapErrors(Function, List> mapper) { + return new Fail<>(partialValue, mapper.apply(badValue)); } @Override - public Result appendError(Bad error) { - return Result.partial(partialValue, AppendableError.concatError(badValue, error)); + public Result appendErrors(List errors) { + var nextErrors = new ArrayList<>(badValue); + nextErrors.addAll(errors); + return new Fail<>(partialValue, nextErrors); } } @@ -98,10 +116,16 @@ public sealed interface Result permits Result.Ok, Result.Fail { } static Result.Fail fail(Bad error) { - return new Fail<>(null, error); + return new Fail<>(null, List.of(error)); + } + + + static Result cast(Result c) { + //noinspection unchecked + return (Result) c; } static Result.Fail partial(@Nullable Good partial, Bad error) { - return new Fail<>(partial, error); + return new Fail<>(partial, List.of(error)); } } diff --git a/src/main/java/moe/nea/pcj/Tuple.java b/src/main/java/moe/nea/pcj/Tuple.java index baaceef..e6207ff 100644 --- a/src/main/java/moe/nea/pcj/Tuple.java +++ b/src/main/java/moe/nea/pcj/Tuple.java @@ -1,16 +1,1030 @@ +// @generated by gentuples.ts package moe.nea.pcj; +@SuppressWarnings("unused") public interface Tuple { - record Tuple2(A first, B second) implements Tuple {} + class Tuple0 implements Tuple { + public R applyTo(Func0 func) { + return func.apply(); + } - record Tuple3(A first, B second, C third) implements Tuple {} + public static Result collect(Tuple0 tuple) { + return + Result.ok(new Tuple0()) + ; + } - record Tuple4(A first, B second, C third, D fourth) implements Tuple {} + public Tuple0 map() { + return new Tuple0(); + } - record Tuple5(A first, B second, C third, D fourth, E fifth) implements Tuple {} + public Tuple0 join(Tuple0 other) { + return new Tuple0(); + } - record Tuple6(A first, B second, C third, D fourth, E fifth, F sixth) implements Tuple {} + public Tuple1 join(Tuple1 other) { + return new Tuple1<>(other.element0); + } - record Tuple7(A first, B second, C third, D fourth, E fifth, F sixth, - G seventh) implements Tuple {} + public Tuple2 join(Tuple2 other) { + return new Tuple2<>(other.element0, other.element1); + } + + public Tuple3 join(Tuple3 other) { + return new Tuple3<>(other.element0, other.element1, other.element2); + } + + public Tuple4 join(Tuple4 other) { + return new Tuple4<>(other.element0, other.element1, other.element2, other.element3); + } + + public Tuple5 join(Tuple5 other) { + return new Tuple5<>(other.element0, other.element1, other.element2, other.element3, other.element4); + } + + public Tuple6 join(Tuple6 other) { + return new Tuple6<>(other.element0, other.element1, other.element2, other.element3, other.element4, other.element5); + } + + public Tuple7 join(Tuple7 other) { + return new Tuple7<>(other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6); + } + + public Tuple8 join(Tuple8 other) { + return new Tuple8<>(other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7); + } + + public Tuple9 join(Tuple9 other) { + return new Tuple9<>(other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8); + } + + public Tuple10 join(Tuple10 other) { + return new Tuple10<>(other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8, other.element9); + } + + public Tuple11 join(Tuple11 other) { + return new Tuple11<>(other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8, other.element9, other.element10); + } + + public Tuple12 join(Tuple12 other) { + return new Tuple12<>(other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8, other.element9, other.element10, other.element11); + } + + public Tuple13 join(Tuple13 other) { + return new Tuple13<>(other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8, other.element9, other.element10, other.element11, other.element12); + } + + public Tuple14 join(Tuple14 other) { + return new Tuple14<>(other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8, other.element9, other.element10, other.element11, other.element12, other.element13); + } + } + + @FunctionalInterface + interface Func0 { + R apply(); + } + + record Tuple1(T0 element0) { + public R applyTo(Func1 func) { + return func.apply(this.element0); + } + + public static Result, R> collect(Tuple1> tuple) { + return + tuple.element0.flatMap(element0 -> + Result.ok(new Tuple1<>(element0)) + ) + ; + } + + public Tuple1 map(Func1 map0) { + return new Tuple1<>(map0.apply(this.element0)); + } + + public Tuple1 join(Tuple0 other) { + return new Tuple1<>(this.element0); + } + + public Tuple2 join(Tuple1 other) { + return new Tuple2<>(this.element0, other.element0); + } + + public Tuple3 join(Tuple2 other) { + return new Tuple3<>(this.element0, other.element0, other.element1); + } + + public Tuple4 join(Tuple3 other) { + return new Tuple4<>(this.element0, other.element0, other.element1, other.element2); + } + + public Tuple5 join(Tuple4 other) { + return new Tuple5<>(this.element0, other.element0, other.element1, other.element2, other.element3); + } + + public Tuple6 join(Tuple5 other) { + return new Tuple6<>(this.element0, other.element0, other.element1, other.element2, other.element3, other.element4); + } + + public Tuple7 join(Tuple6 other) { + return new Tuple7<>(this.element0, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5); + } + + public Tuple8 join(Tuple7 other) { + return new Tuple8<>(this.element0, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6); + } + + public Tuple9 join(Tuple8 other) { + return new Tuple9<>(this.element0, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7); + } + + public Tuple10 join(Tuple9 other) { + return new Tuple10<>(this.element0, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8); + } + + public Tuple11 join(Tuple10 other) { + return new Tuple11<>(this.element0, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8, other.element9); + } + + public Tuple12 join(Tuple11 other) { + return new Tuple12<>(this.element0, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8, other.element9, other.element10); + } + + public Tuple13 join(Tuple12 other) { + return new Tuple13<>(this.element0, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8, other.element9, other.element10, other.element11); + } + + public Tuple14 join(Tuple13 other) { + return new Tuple14<>(this.element0, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8, other.element9, other.element10, other.element11, other.element12); + } + } + + @FunctionalInterface + interface Func1 { + R apply(T0 arg0); + } + + record Tuple2(T0 element0, T1 element1) { + public R applyTo(Func2 func) { + return func.apply(this.element0, this.element1); + } + + public static Result, R> collect(Tuple2, Result> tuple) { + return + tuple.element0.flatMap(element0 -> + tuple.element1.flatMap(element1 -> + Result.ok(new Tuple2<>(element0, element1)) + ) + ) + ; + } + + public Tuple2 map(Func1 map0, Func1 map1) { + return new Tuple2<>(map0.apply(this.element0), map1.apply(this.element1)); + } + + public Tuple2 join(Tuple0 other) { + return new Tuple2<>(this.element0, this.element1); + } + + public Tuple3 join(Tuple1 other) { + return new Tuple3<>(this.element0, this.element1, other.element0); + } + + public Tuple4 join(Tuple2 other) { + return new Tuple4<>(this.element0, this.element1, other.element0, other.element1); + } + + public Tuple5 join(Tuple3 other) { + return new Tuple5<>(this.element0, this.element1, other.element0, other.element1, other.element2); + } + + public Tuple6 join(Tuple4 other) { + return new Tuple6<>(this.element0, this.element1, other.element0, other.element1, other.element2, other.element3); + } + + public Tuple7 join(Tuple5 other) { + return new Tuple7<>(this.element0, this.element1, other.element0, other.element1, other.element2, other.element3, other.element4); + } + + public Tuple8 join(Tuple6 other) { + return new Tuple8<>(this.element0, this.element1, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5); + } + + public Tuple9 join(Tuple7 other) { + return new Tuple9<>(this.element0, this.element1, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6); + } + + public Tuple10 join(Tuple8 other) { + return new Tuple10<>(this.element0, this.element1, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7); + } + + public Tuple11 join(Tuple9 other) { + return new Tuple11<>(this.element0, this.element1, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8); + } + + public Tuple12 join(Tuple10 other) { + return new Tuple12<>(this.element0, this.element1, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8, other.element9); + } + + public Tuple13 join(Tuple11 other) { + return new Tuple13<>(this.element0, this.element1, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8, other.element9, other.element10); + } + + public Tuple14 join(Tuple12 other) { + return new Tuple14<>(this.element0, this.element1, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8, other.element9, other.element10, other.element11); + } + } + + @FunctionalInterface + interface Func2 { + R apply(T0 arg0, T1 arg1); + } + + record Tuple3(T0 element0, T1 element1, T2 element2) { + public R applyTo(Func3 func) { + return func.apply(this.element0, this.element1, this.element2); + } + + public static Result, R> collect(Tuple3, Result, Result> tuple) { + return + tuple.element0.flatMap(element0 -> + tuple.element1.flatMap(element1 -> + tuple.element2.flatMap(element2 -> + Result.ok(new Tuple3<>(element0, element1, element2)) + ) + ) + ) + ; + } + + public Tuple3 map(Func1 map0, Func1 map1, Func1 map2) { + return new Tuple3<>(map0.apply(this.element0), map1.apply(this.element1), map2.apply(this.element2)); + } + + public Tuple3 join(Tuple0 other) { + return new Tuple3<>(this.element0, this.element1, this.element2); + } + + public Tuple4 join(Tuple1 other) { + return new Tuple4<>(this.element0, this.element1, this.element2, other.element0); + } + + public Tuple5 join(Tuple2 other) { + return new Tuple5<>(this.element0, this.element1, this.element2, other.element0, other.element1); + } + + public Tuple6 join(Tuple3 other) { + return new Tuple6<>(this.element0, this.element1, this.element2, other.element0, other.element1, other.element2); + } + + public Tuple7 join(Tuple4 other) { + return new Tuple7<>(this.element0, this.element1, this.element2, other.element0, other.element1, other.element2, other.element3); + } + + public Tuple8 join(Tuple5 other) { + return new Tuple8<>(this.element0, this.element1, this.element2, other.element0, other.element1, other.element2, other.element3, other.element4); + } + + public Tuple9 join(Tuple6 other) { + return new Tuple9<>(this.element0, this.element1, this.element2, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5); + } + + public Tuple10 join(Tuple7 other) { + return new Tuple10<>(this.element0, this.element1, this.element2, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6); + } + + public Tuple11 join(Tuple8 other) { + return new Tuple11<>(this.element0, this.element1, this.element2, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7); + } + + public Tuple12 join(Tuple9 other) { + return new Tuple12<>(this.element0, this.element1, this.element2, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8); + } + + public Tuple13 join(Tuple10 other) { + return new Tuple13<>(this.element0, this.element1, this.element2, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8, other.element9); + } + + public Tuple14 join(Tuple11 other) { + return new Tuple14<>(this.element0, this.element1, this.element2, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8, other.element9, other.element10); + } + } + + @FunctionalInterface + interface Func3 { + R apply(T0 arg0, T1 arg1, T2 arg2); + } + + record Tuple4(T0 element0, T1 element1, T2 element2, T3 element3) { + public R applyTo(Func4 func) { + return func.apply(this.element0, this.element1, this.element2, this.element3); + } + + public static Result, R> collect(Tuple4, Result, Result, Result> tuple) { + return + tuple.element0.flatMap(element0 -> + tuple.element1.flatMap(element1 -> + tuple.element2.flatMap(element2 -> + tuple.element3.flatMap(element3 -> + Result.ok(new Tuple4<>(element0, element1, element2, element3)) + ) + ) + ) + ) + ; + } + + public Tuple4 map(Func1 map0, Func1 map1, Func1 map2, Func1 map3) { + return new Tuple4<>(map0.apply(this.element0), map1.apply(this.element1), map2.apply(this.element2), map3.apply(this.element3)); + } + + public Tuple4 join(Tuple0 other) { + return new Tuple4<>(this.element0, this.element1, this.element2, this.element3); + } + + public Tuple5 join(Tuple1 other) { + return new Tuple5<>(this.element0, this.element1, this.element2, this.element3, other.element0); + } + + public Tuple6 join(Tuple2 other) { + return new Tuple6<>(this.element0, this.element1, this.element2, this.element3, other.element0, other.element1); + } + + public Tuple7 join(Tuple3 other) { + return new Tuple7<>(this.element0, this.element1, this.element2, this.element3, other.element0, other.element1, other.element2); + } + + public Tuple8 join(Tuple4 other) { + return new Tuple8<>(this.element0, this.element1, this.element2, this.element3, other.element0, other.element1, other.element2, other.element3); + } + + public Tuple9 join(Tuple5 other) { + return new Tuple9<>(this.element0, this.element1, this.element2, this.element3, other.element0, other.element1, other.element2, other.element3, other.element4); + } + + public Tuple10 join(Tuple6 other) { + return new Tuple10<>(this.element0, this.element1, this.element2, this.element3, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5); + } + + public Tuple11 join(Tuple7 other) { + return new Tuple11<>(this.element0, this.element1, this.element2, this.element3, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6); + } + + public Tuple12 join(Tuple8 other) { + return new Tuple12<>(this.element0, this.element1, this.element2, this.element3, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7); + } + + public Tuple13 join(Tuple9 other) { + return new Tuple13<>(this.element0, this.element1, this.element2, this.element3, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8); + } + + public Tuple14 join(Tuple10 other) { + return new Tuple14<>(this.element0, this.element1, this.element2, this.element3, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8, other.element9); + } + } + + @FunctionalInterface + interface Func4 { + R apply(T0 arg0, T1 arg1, T2 arg2, T3 arg3); + } + + record Tuple5(T0 element0, T1 element1, T2 element2, T3 element3, T4 element4) { + public R applyTo(Func5 func) { + return func.apply(this.element0, this.element1, this.element2, this.element3, this.element4); + } + + public static Result, R> collect(Tuple5, Result, Result, Result, Result> tuple) { + return + tuple.element0.flatMap(element0 -> + tuple.element1.flatMap(element1 -> + tuple.element2.flatMap(element2 -> + tuple.element3.flatMap(element3 -> + tuple.element4.flatMap(element4 -> + Result.ok(new Tuple5<>(element0, element1, element2, element3, element4)) + ) + ) + ) + ) + ) + ; + } + + public Tuple5 map(Func1 map0, Func1 map1, Func1 map2, Func1 map3, Func1 map4) { + return new Tuple5<>(map0.apply(this.element0), map1.apply(this.element1), map2.apply(this.element2), map3.apply(this.element3), map4.apply(this.element4)); + } + + public Tuple5 join(Tuple0 other) { + return new Tuple5<>(this.element0, this.element1, this.element2, this.element3, this.element4); + } + + public Tuple6 join(Tuple1 other) { + return new Tuple6<>(this.element0, this.element1, this.element2, this.element3, this.element4, other.element0); + } + + public Tuple7 join(Tuple2 other) { + return new Tuple7<>(this.element0, this.element1, this.element2, this.element3, this.element4, other.element0, other.element1); + } + + public Tuple8 join(Tuple3 other) { + return new Tuple8<>(this.element0, this.element1, this.element2, this.element3, this.element4, other.element0, other.element1, other.element2); + } + + public Tuple9 join(Tuple4 other) { + return new Tuple9<>(this.element0, this.element1, this.element2, this.element3, this.element4, other.element0, other.element1, other.element2, other.element3); + } + + public Tuple10 join(Tuple5 other) { + return new Tuple10<>(this.element0, this.element1, this.element2, this.element3, this.element4, other.element0, other.element1, other.element2, other.element3, other.element4); + } + + public Tuple11 join(Tuple6 other) { + return new Tuple11<>(this.element0, this.element1, this.element2, this.element3, this.element4, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5); + } + + public Tuple12 join(Tuple7 other) { + return new Tuple12<>(this.element0, this.element1, this.element2, this.element3, this.element4, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6); + } + + public Tuple13 join(Tuple8 other) { + return new Tuple13<>(this.element0, this.element1, this.element2, this.element3, this.element4, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7); + } + + public Tuple14 join(Tuple9 other) { + return new Tuple14<>(this.element0, this.element1, this.element2, this.element3, this.element4, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8); + } + } + + @FunctionalInterface + interface Func5 { + R apply(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4); + } + + record Tuple6(T0 element0, T1 element1, T2 element2, T3 element3, T4 element4, + T5 element5) { + public R applyTo(Func6 func) { + return func.apply(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5); + } + + public static Result, R> collect(Tuple6, Result, Result, Result, Result, Result> tuple) { + return + tuple.element0.flatMap(element0 -> + tuple.element1.flatMap(element1 -> + tuple.element2.flatMap(element2 -> + tuple.element3.flatMap(element3 -> + tuple.element4.flatMap(element4 -> + tuple.element5.flatMap(element5 -> + Result.ok(new Tuple6<>(element0, element1, element2, element3, element4, element5)) + ) + ) + ) + ) + ) + ) + ; + } + + public Tuple6 map(Func1 map0, Func1 map1, Func1 map2, Func1 map3, Func1 map4, Func1 map5) { + return new Tuple6<>(map0.apply(this.element0), map1.apply(this.element1), map2.apply(this.element2), map3.apply(this.element3), map4.apply(this.element4), map5.apply(this.element5)); + } + + public Tuple6 join(Tuple0 other) { + return new Tuple6<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5); + } + + public Tuple7 join(Tuple1 other) { + return new Tuple7<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, other.element0); + } + + public Tuple8 join(Tuple2 other) { + return new Tuple8<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, other.element0, other.element1); + } + + public Tuple9 join(Tuple3 other) { + return new Tuple9<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, other.element0, other.element1, other.element2); + } + + public Tuple10 join(Tuple4 other) { + return new Tuple10<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, other.element0, other.element1, other.element2, other.element3); + } + + public Tuple11 join(Tuple5 other) { + return new Tuple11<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, other.element0, other.element1, other.element2, other.element3, other.element4); + } + + public Tuple12 join(Tuple6 other) { + return new Tuple12<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5); + } + + public Tuple13 join(Tuple7 other) { + return new Tuple13<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6); + } + + public Tuple14 join(Tuple8 other) { + return new Tuple14<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7); + } + } + + @FunctionalInterface + interface Func6 { + R apply(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); + } + + record Tuple7(T0 element0, T1 element1, T2 element2, T3 element3, T4 element4, + T5 element5, T6 element6) { + public R applyTo(Func7 func) { + return func.apply(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6); + } + + public static Result, R> collect(Tuple7, Result, Result, Result, Result, Result, Result> tuple) { + return + tuple.element0.flatMap(element0 -> + tuple.element1.flatMap(element1 -> + tuple.element2.flatMap(element2 -> + tuple.element3.flatMap(element3 -> + tuple.element4.flatMap(element4 -> + tuple.element5.flatMap(element5 -> + tuple.element6.flatMap(element6 -> + Result.ok(new Tuple7<>(element0, element1, element2, element3, element4, element5, element6)) + ) + ) + ) + ) + ) + ) + ) + ; + } + + public Tuple7 map(Func1 map0, Func1 map1, Func1 map2, Func1 map3, Func1 map4, Func1 map5, Func1 map6) { + return new Tuple7<>(map0.apply(this.element0), map1.apply(this.element1), map2.apply(this.element2), map3.apply(this.element3), map4.apply(this.element4), map5.apply(this.element5), map6.apply(this.element6)); + } + + public Tuple7 join(Tuple0 other) { + return new Tuple7<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6); + } + + public Tuple8 join(Tuple1 other) { + return new Tuple8<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, other.element0); + } + + public Tuple9 join(Tuple2 other) { + return new Tuple9<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, other.element0, other.element1); + } + + public Tuple10 join(Tuple3 other) { + return new Tuple10<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, other.element0, other.element1, other.element2); + } + + public Tuple11 join(Tuple4 other) { + return new Tuple11<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, other.element0, other.element1, other.element2, other.element3); + } + + public Tuple12 join(Tuple5 other) { + return new Tuple12<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, other.element0, other.element1, other.element2, other.element3, other.element4); + } + + public Tuple13 join(Tuple6 other) { + return new Tuple13<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5); + } + + public Tuple14 join(Tuple7 other) { + return new Tuple14<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6); + } + } + + @FunctionalInterface + interface Func7 { + R apply(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6); + } + + record Tuple8(T0 element0, T1 element1, T2 element2, T3 element3, T4 element4, + T5 element5, T6 element6, T7 element7) { + public R applyTo(Func8 func) { + return func.apply(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7); + } + + public static Result, R> collect(Tuple8, Result, Result, Result, Result, Result, Result, Result> tuple) { + return + tuple.element0.flatMap(element0 -> + tuple.element1.flatMap(element1 -> + tuple.element2.flatMap(element2 -> + tuple.element3.flatMap(element3 -> + tuple.element4.flatMap(element4 -> + tuple.element5.flatMap(element5 -> + tuple.element6.flatMap(element6 -> + tuple.element7.flatMap(element7 -> + Result.ok(new Tuple8<>(element0, element1, element2, element3, element4, element5, element6, element7)) + ) + ) + ) + ) + ) + ) + ) + ) + ; + } + + public Tuple8 map(Func1 map0, Func1 map1, Func1 map2, Func1 map3, Func1 map4, Func1 map5, Func1 map6, Func1 map7) { + return new Tuple8<>(map0.apply(this.element0), map1.apply(this.element1), map2.apply(this.element2), map3.apply(this.element3), map4.apply(this.element4), map5.apply(this.element5), map6.apply(this.element6), map7.apply(this.element7)); + } + + public Tuple8 join(Tuple0 other) { + return new Tuple8<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7); + } + + public Tuple9 join(Tuple1 other) { + return new Tuple9<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, other.element0); + } + + public Tuple10 join(Tuple2 other) { + return new Tuple10<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, other.element0, other.element1); + } + + public Tuple11 join(Tuple3 other) { + return new Tuple11<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, other.element0, other.element1, other.element2); + } + + public Tuple12 join(Tuple4 other) { + return new Tuple12<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, other.element0, other.element1, other.element2, other.element3); + } + + public Tuple13 join(Tuple5 other) { + return new Tuple13<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, other.element0, other.element1, other.element2, other.element3, other.element4); + } + + public Tuple14 join(Tuple6 other) { + return new Tuple14<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, other.element0, other.element1, other.element2, other.element3, other.element4, other.element5); + } + } + + @FunctionalInterface + interface Func8 { + R apply(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7); + } + + record Tuple9(T0 element0, T1 element1, T2 element2, T3 element3, T4 element4, + T5 element5, T6 element6, T7 element7, T8 element8) { + public R applyTo(Func9 func) { + return func.apply(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8); + } + + public static Result, R> collect(Tuple9, Result, Result, Result, Result, Result, Result, Result, Result> tuple) { + return + tuple.element0.flatMap(element0 -> + tuple.element1.flatMap(element1 -> + tuple.element2.flatMap(element2 -> + tuple.element3.flatMap(element3 -> + tuple.element4.flatMap(element4 -> + tuple.element5.flatMap(element5 -> + tuple.element6.flatMap(element6 -> + tuple.element7.flatMap(element7 -> + tuple.element8.flatMap(element8 -> + Result.ok(new Tuple9<>(element0, element1, element2, element3, element4, element5, element6, element7, element8)) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ; + } + + public Tuple9 map(Func1 map0, Func1 map1, Func1 map2, Func1 map3, Func1 map4, Func1 map5, Func1 map6, Func1 map7, Func1 map8) { + return new Tuple9<>(map0.apply(this.element0), map1.apply(this.element1), map2.apply(this.element2), map3.apply(this.element3), map4.apply(this.element4), map5.apply(this.element5), map6.apply(this.element6), map7.apply(this.element7), map8.apply(this.element8)); + } + + public Tuple9 join(Tuple0 other) { + return new Tuple9<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8); + } + + public Tuple10 join(Tuple1 other) { + return new Tuple10<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, other.element0); + } + + public Tuple11 join(Tuple2 other) { + return new Tuple11<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, other.element0, other.element1); + } + + public Tuple12 join(Tuple3 other) { + return new Tuple12<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, other.element0, other.element1, other.element2); + } + + public Tuple13 join(Tuple4 other) { + return new Tuple13<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, other.element0, other.element1, other.element2, other.element3); + } + + public Tuple14 join(Tuple5 other) { + return new Tuple14<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, other.element0, other.element1, other.element2, other.element3, other.element4); + } + } + + @FunctionalInterface + interface Func9 { + R apply(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8); + } + + record Tuple10(T0 element0, T1 element1, T2 element2, T3 element3, + T4 element4, T5 element5, T6 element6, T7 element7, + T8 element8, T9 element9) { + public R applyTo(Func10 func) { + return func.apply(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9); + } + + public static Result, R> collect(Tuple10, Result, Result, Result, Result, Result, Result, Result, Result, Result> tuple) { + return + tuple.element0.flatMap(element0 -> + tuple.element1.flatMap(element1 -> + tuple.element2.flatMap(element2 -> + tuple.element3.flatMap(element3 -> + tuple.element4.flatMap(element4 -> + tuple.element5.flatMap(element5 -> + tuple.element6.flatMap(element6 -> + tuple.element7.flatMap(element7 -> + tuple.element8.flatMap(element8 -> + tuple.element9.flatMap(element9 -> + Result.ok(new Tuple10<>(element0, element1, element2, element3, element4, element5, element6, element7, element8, element9)) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ; + } + + public Tuple10 map(Func1 map0, Func1 map1, Func1 map2, Func1 map3, Func1 map4, Func1 map5, Func1 map6, Func1 map7, Func1 map8, Func1 map9) { + return new Tuple10<>(map0.apply(this.element0), map1.apply(this.element1), map2.apply(this.element2), map3.apply(this.element3), map4.apply(this.element4), map5.apply(this.element5), map6.apply(this.element6), map7.apply(this.element7), map8.apply(this.element8), map9.apply(this.element9)); + } + + public Tuple10 join(Tuple0 other) { + return new Tuple10<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9); + } + + public Tuple11 join(Tuple1 other) { + return new Tuple11<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9, other.element0); + } + + public Tuple12 join(Tuple2 other) { + return new Tuple12<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9, other.element0, other.element1); + } + + public Tuple13 join(Tuple3 other) { + return new Tuple13<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9, other.element0, other.element1, other.element2); + } + + public Tuple14 join(Tuple4 other) { + return new Tuple14<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9, other.element0, other.element1, other.element2, other.element3); + } + } + + @FunctionalInterface + interface Func10 { + R apply(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9); + } + + record Tuple11(T0 element0, T1 element1, T2 element2, T3 element3, + T4 element4, T5 element5, T6 element6, T7 element7, + T8 element8, T9 element9, T10 element10) { + public R applyTo(Func11 func) { + return func.apply(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9, this.element10); + } + + public static Result, R> collect(Tuple11, Result, Result, Result, Result, Result, Result, Result, Result, Result, Result> tuple) { + return + tuple.element0.flatMap(element0 -> + tuple.element1.flatMap(element1 -> + tuple.element2.flatMap(element2 -> + tuple.element3.flatMap(element3 -> + tuple.element4.flatMap(element4 -> + tuple.element5.flatMap(element5 -> + tuple.element6.flatMap(element6 -> + tuple.element7.flatMap(element7 -> + tuple.element8.flatMap(element8 -> + tuple.element9.flatMap(element9 -> + tuple.element10.flatMap(element10 -> + Result.ok(new Tuple11<>(element0, element1, element2, element3, element4, element5, element6, element7, element8, element9, element10)) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ; + } + + public Tuple11 map(Func1 map0, Func1 map1, Func1 map2, Func1 map3, Func1 map4, Func1 map5, Func1 map6, Func1 map7, Func1 map8, Func1 map9, Func1 map10) { + return new Tuple11<>(map0.apply(this.element0), map1.apply(this.element1), map2.apply(this.element2), map3.apply(this.element3), map4.apply(this.element4), map5.apply(this.element5), map6.apply(this.element6), map7.apply(this.element7), map8.apply(this.element8), map9.apply(this.element9), map10.apply(this.element10)); + } + + public Tuple11 join(Tuple0 other) { + return new Tuple11<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9, this.element10); + } + + public Tuple12 join(Tuple1 other) { + return new Tuple12<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9, this.element10, other.element0); + } + + public Tuple13 join(Tuple2 other) { + return new Tuple13<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9, this.element10, other.element0, other.element1); + } + + public Tuple14 join(Tuple3 other) { + return new Tuple14<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9, this.element10, other.element0, other.element1, other.element2); + } + } + + @FunctionalInterface + interface Func11 { + R apply(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10); + } + + record Tuple12(T0 element0, T1 element1, T2 element2, T3 element3, + T4 element4, T5 element5, T6 element6, T7 element7, + T8 element8, T9 element9, T10 element10, + T11 element11) { + public R applyTo(Func12 func) { + return func.apply(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9, this.element10, this.element11); + } + + public static Result, R> collect(Tuple12, Result, Result, Result, Result, Result, Result, Result, Result, Result, Result, Result> tuple) { + return + tuple.element0.flatMap(element0 -> + tuple.element1.flatMap(element1 -> + tuple.element2.flatMap(element2 -> + tuple.element3.flatMap(element3 -> + tuple.element4.flatMap(element4 -> + tuple.element5.flatMap(element5 -> + tuple.element6.flatMap(element6 -> + tuple.element7.flatMap(element7 -> + tuple.element8.flatMap(element8 -> + tuple.element9.flatMap(element9 -> + tuple.element10.flatMap(element10 -> + tuple.element11.flatMap(element11 -> + Result.ok(new Tuple12<>(element0, element1, element2, element3, element4, element5, element6, element7, element8, element9, element10, element11)) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ; + } + + public Tuple12 map(Func1 map0, Func1 map1, Func1 map2, Func1 map3, Func1 map4, Func1 map5, Func1 map6, Func1 map7, Func1 map8, Func1 map9, Func1 map10, Func1 map11) { + return new Tuple12<>(map0.apply(this.element0), map1.apply(this.element1), map2.apply(this.element2), map3.apply(this.element3), map4.apply(this.element4), map5.apply(this.element5), map6.apply(this.element6), map7.apply(this.element7), map8.apply(this.element8), map9.apply(this.element9), map10.apply(this.element10), map11.apply(this.element11)); + } + + public Tuple12 join(Tuple0 other) { + return new Tuple12<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9, this.element10, this.element11); + } + + public Tuple13 join(Tuple1 other) { + return new Tuple13<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9, this.element10, this.element11, other.element0); + } + + public Tuple14 join(Tuple2 other) { + return new Tuple14<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9, this.element10, this.element11, other.element0, other.element1); + } + } + + @FunctionalInterface + interface Func12 { + R apply(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11); + } + + record Tuple13(T0 element0, T1 element1, T2 element2, + T3 element3, T4 element4, T5 element5, + T6 element6, T7 element7, T8 element8, + T9 element9, T10 element10, T11 element11, + T12 element12) { + public R applyTo(Func13 func) { + return func.apply(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9, this.element10, this.element11, this.element12); + } + + public static Result, R> collect(Tuple13, Result, Result, Result, Result, Result, Result, Result, Result, Result, Result, Result, Result> tuple) { + return + tuple.element0.flatMap(element0 -> + tuple.element1.flatMap(element1 -> + tuple.element2.flatMap(element2 -> + tuple.element3.flatMap(element3 -> + tuple.element4.flatMap(element4 -> + tuple.element5.flatMap(element5 -> + tuple.element6.flatMap(element6 -> + tuple.element7.flatMap(element7 -> + tuple.element8.flatMap(element8 -> + tuple.element9.flatMap(element9 -> + tuple.element10.flatMap(element10 -> + tuple.element11.flatMap(element11 -> + tuple.element12.flatMap(element12 -> + Result.ok(new Tuple13<>(element0, element1, element2, element3, element4, element5, element6, element7, element8, element9, element10, element11, element12)) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ; + } + + public Tuple13 map(Func1 map0, Func1 map1, Func1 map2, Func1 map3, Func1 map4, Func1 map5, Func1 map6, Func1 map7, Func1 map8, Func1 map9, Func1 map10, Func1 map11, Func1 map12) { + return new Tuple13<>(map0.apply(this.element0), map1.apply(this.element1), map2.apply(this.element2), map3.apply(this.element3), map4.apply(this.element4), map5.apply(this.element5), map6.apply(this.element6), map7.apply(this.element7), map8.apply(this.element8), map9.apply(this.element9), map10.apply(this.element10), map11.apply(this.element11), map12.apply(this.element12)); + } + + public Tuple13 join(Tuple0 other) { + return new Tuple13<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9, this.element10, this.element11, this.element12); + } + + public Tuple14 join(Tuple1 other) { + return new Tuple14<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9, this.element10, this.element11, this.element12, other.element0); + } + } + + @FunctionalInterface + interface Func13 { + R apply(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12); + } + + record Tuple14(T0 element0, T1 element1, T2 element2, + T3 element3, T4 element4, T5 element5, + T6 element6, T7 element7, T8 element8, + T9 element9, T10 element10, + T11 element11, T12 element12, + T13 element13) { + public R applyTo(Func14 func) { + return func.apply(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9, this.element10, this.element11, this.element12, this.element13); + } + + public static Result, R> collect(Tuple14, Result, Result, Result, Result, Result, Result, Result, Result, Result, Result, Result, Result, Result> tuple) { + return + tuple.element0.flatMap(element0 -> + tuple.element1.flatMap(element1 -> + tuple.element2.flatMap(element2 -> + tuple.element3.flatMap(element3 -> + tuple.element4.flatMap(element4 -> + tuple.element5.flatMap(element5 -> + tuple.element6.flatMap(element6 -> + tuple.element7.flatMap(element7 -> + tuple.element8.flatMap(element8 -> + tuple.element9.flatMap(element9 -> + tuple.element10.flatMap(element10 -> + tuple.element11.flatMap(element11 -> + tuple.element12.flatMap(element12 -> + tuple.element13.flatMap(element13 -> + Result.ok(new Tuple14<>(element0, element1, element2, element3, element4, element5, element6, element7, element8, element9, element10, element11, element12, element13)) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ; + } + + public Tuple14 map(Func1 map0, Func1 map1, Func1 map2, Func1 map3, Func1 map4, Func1 map5, Func1 map6, Func1 map7, Func1 map8, Func1 map9, Func1 map10, Func1 map11, Func1 map12, Func1 map13) { + return new Tuple14<>(map0.apply(this.element0), map1.apply(this.element1), map2.apply(this.element2), map3.apply(this.element3), map4.apply(this.element4), map5.apply(this.element5), map6.apply(this.element6), map7.apply(this.element7), map8.apply(this.element8), map9.apply(this.element9), map10.apply(this.element10), map11.apply(this.element11), map12.apply(this.element12), map13.apply(this.element13)); + } + + public Tuple14 join(Tuple0 other) { + return new Tuple14<>(this.element0, this.element1, this.element2, this.element3, this.element4, this.element5, this.element6, this.element7, this.element8, this.element9, this.element10, this.element11, this.element12, this.element13); + } + } + + @FunctionalInterface + interface Func14 { + R apply(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13); + } } diff --git a/src/main/java/moe/nea/pcj/json/AtField.java b/src/main/java/moe/nea/pcj/json/AtField.java new file mode 100644 index 0000000..3780e38 --- /dev/null +++ b/src/main/java/moe/nea/pcj/json/AtField.java @@ -0,0 +1,4 @@ +package moe.nea.pcj.json; + +public record AtField(String field, JsonLikeError error) implements JsonLikeError { +} diff --git a/src/main/java/moe/nea/pcj/json/BasicCodecs.java b/src/main/java/moe/nea/pcj/json/BasicCodecs.java new file mode 100644 index 0000000..8f957f9 --- /dev/null +++ b/src/main/java/moe/nea/pcj/json/BasicCodecs.java @@ -0,0 +1,51 @@ +package moe.nea.pcj.json; + +import moe.nea.pcj.Result; + +public class BasicCodecs { + protected BasicCodecs() {} + + public static BasicCodecs create() { + return new BasicCodecs<>(); + } + + public final JsonCodec STRING = new JsonCodec<>() { + @Override + public Result decode(Format format, JsonLikeOperations ops) { + return ops.getString(format); + } + + @Override + public Result encode(String data, JsonLikeOperations ops) { + return Result.ok(ops.createString(data)); + } + }; + + public final JsonCodec FLOAT = new JsonCodec() { + @Override + public Result decode(Format format, JsonLikeOperations ops) { + return ops.getNumeric(format).map(Number::floatValue); + } + + @Override + public Result encode(Float data, JsonLikeOperations ops) { + return Result.ok(ops.createNumeric(data)); + } + }; + + public final JsonCodec INTEGER = new JsonCodec<>() { + @Override + public Result decode(Format format, JsonLikeOperations ops) { + return ops.getNumeric(format).map(Number::intValue); // TODO: filter for valid ints + } + + @Override + public Result encode(Integer data, JsonLikeOperations ops) { + return Result.ok(ops.createNumeric(data)); + } + }; + + public JsonCodec objectCodec() { + + } +} \ No newline at end of file diff --git a/src/main/java/moe/nea/pcj/json/DuplicateJsonKey.java b/src/main/java/moe/nea/pcj/json/DuplicateJsonKey.java new file mode 100644 index 0000000..13d81db --- /dev/null +++ b/src/main/java/moe/nea/pcj/json/DuplicateJsonKey.java @@ -0,0 +1,4 @@ +package moe.nea.pcj.json; + +public record DuplicateJsonKey(String key) implements JsonLikeError { +} diff --git a/src/main/java/moe/nea/pcj/json/JsonCodec.java b/src/main/java/moe/nea/pcj/json/JsonCodec.java new file mode 100644 index 0000000..65f4a5e --- /dev/null +++ b/src/main/java/moe/nea/pcj/json/JsonCodec.java @@ -0,0 +1,31 @@ +package moe.nea.pcj.json; + +import moe.nea.pcj.Codec; +import moe.nea.pcj.Result; + +public interface JsonCodec extends Codec< + T, Format, JsonLikeOperations, + JsonLikeError, JsonLikeError> { + + default MapCodec fieldOf(String key) { + return new MapCodec<>() { + @Override + public Result decode(RecordView record, JsonLikeOperations ops) { + return record.get(key) + .map(element -> Result.cast( + JsonCodec.this.decode(element, ops) + .mapError(it -> new AtField(key, it)))) + .orElseGet(() -> Result.fail(new MissingKey(key))); + } + + @Override + public Result, JsonLikeError> encode(T value, JsonLikeOperations ops) { + var record = ops.createObject(); + return Result.cast(JsonCodec.this.encode(value, ops)) + .mapError(it -> new AtField(key, it)) + .flatMap(json -> Result.cast(record.add(key, json).map(unit -> record))); + } + + }; + } +} diff --git a/src/main/java/moe/nea/pcj/json/JsonLikeError.java b/src/main/java/moe/nea/pcj/json/JsonLikeError.java new file mode 100644 index 0000000..609bd84 --- /dev/null +++ b/src/main/java/moe/nea/pcj/json/JsonLikeError.java @@ -0,0 +1,4 @@ +package moe.nea.pcj.json; + +public interface JsonLikeError { +} diff --git a/src/main/java/moe/nea/pcj/json/JsonLikeOperations.java b/src/main/java/moe/nea/pcj/json/JsonLikeOperations.java new file mode 100644 index 0000000..7bb0162 --- /dev/null +++ b/src/main/java/moe/nea/pcj/json/JsonLikeOperations.java @@ -0,0 +1,32 @@ +package moe.nea.pcj.json; + +import moe.nea.pcj.Operation; +import moe.nea.pcj.Result; +import moe.nea.pcj.Unit; + +public interface JsonLikeOperations extends Operation { + + Format createNull(Unit value); + + Result getNull(Format element); + + Format createNumeric(Number value); + + Result getNumeric(Format element); + + Format createString(String value); + + Result getString(Format element); + + Format createBoolean(boolean value); + + Result getBoolean(Format format); + + RecordBuilder createObject(); + + Result, ? extends JsonLikeError> getObject(Format format); + + ListBuilder createList(); + + Result, ? extends JsonLikeError> getList(Format format); +} diff --git a/src/main/java/moe/nea/pcj/json/ListBuilder.java b/src/main/java/moe/nea/pcj/json/ListBuilder.java new file mode 100644 index 0000000..c6e9220 --- /dev/null +++ b/src/main/java/moe/nea/pcj/json/ListBuilder.java @@ -0,0 +1,9 @@ +package moe.nea.pcj.json; + +public interface ListBuilder extends ListView { + Format complete(); + + void add(ElementFormat value); + + void set(int index, ElementFormat value); +} diff --git a/src/main/java/moe/nea/pcj/json/ListView.java b/src/main/java/moe/nea/pcj/json/ListView.java new file mode 100644 index 0000000..dcc6e37 --- /dev/null +++ b/src/main/java/moe/nea/pcj/json/ListView.java @@ -0,0 +1,14 @@ +package moe.nea.pcj.json; + +import java.util.Optional; + +public interface ListView { + int length(); + + default Optional getSafe(int index) { + if (index < 0 || index >= length()) return Optional.empty(); + return Optional.of(getUnsafe(index)); + } + + Format getUnsafe(int index); +} diff --git a/src/main/java/moe/nea/pcj/json/MapCodec.java b/src/main/java/moe/nea/pcj/json/MapCodec.java new file mode 100644 index 0000000..468e4cf --- /dev/null +++ b/src/main/java/moe/nea/pcj/json/MapCodec.java @@ -0,0 +1,17 @@ +package moe.nea.pcj.json; + +import moe.nea.pcj.Result; + +import java.util.function.Function; + +public interface MapCodec { + Result decode( + RecordView record, + JsonLikeOperations ops); + + Result, JsonLikeError> encode(T value, JsonLikeOperations ops); + + default RecordCodec withGetter(Function getter) { + return new RecordCodec<>(this, getter); + } +} diff --git a/src/main/java/moe/nea/pcj/json/MissingKey.java b/src/main/java/moe/nea/pcj/json/MissingKey.java new file mode 100644 index 0000000..3dad05c --- /dev/null +++ b/src/main/java/moe/nea/pcj/json/MissingKey.java @@ -0,0 +1,4 @@ +package moe.nea.pcj.json; + +public record MissingKey(String missingKey) implements JsonLikeError { +} diff --git a/src/main/java/moe/nea/pcj/json/RecordBuilder.java b/src/main/java/moe/nea/pcj/json/RecordBuilder.java new file mode 100644 index 0000000..c610f27 --- /dev/null +++ b/src/main/java/moe/nea/pcj/json/RecordBuilder.java @@ -0,0 +1,12 @@ +package moe.nea.pcj.json; + +import moe.nea.pcj.Result; +import moe.nea.pcj.Unit; + +public interface RecordBuilder extends RecordView { + Result add(String key, ElementFormat value); + + Result, JsonLikeError> mergeWith(RecordBuilder other); + + ElementFormat complete(); +} diff --git a/src/main/java/moe/nea/pcj/json/RecordCodec.java b/src/main/java/moe/nea/pcj/json/RecordCodec.java new file mode 100644 index 0000000..7ba8815 --- /dev/null +++ b/src/main/java/moe/nea/pcj/json/RecordCodec.java @@ -0,0 +1,59 @@ +package moe.nea.pcj.json; + +import moe.nea.pcj.Codec; +import moe.nea.pcj.Result; +import moe.nea.pcj.Tuple; + +import java.util.function.Function; +import java.util.stream.Stream; + +public record RecordCodec( + MapCodec codec, + Function getter +) { + + private Result, JsonLikeError> enc(O data, JsonLikeOperations ops) { + return codec().encode(getter().apply(data), ops); + } + + private Result dec(RecordView data, JsonLikeOperations ops) { + return codec().decode(data, ops); + } + + private static Result, JsonLikeError> merge(Result, JsonLikeError> left, Result, JsonLikeError> right) { + return left.flatMap(l -> right.flatMap(l::mergeWith)); + } + + abstract static class RecordCompleteCodec implements JsonCodec { + @Override + public Result decode(Format format, JsonLikeOperations ops) { + return Result., JsonLikeError>cast(ops.getObject(format)) + .flatMap(record -> (decode(record, ops))); + } + + protected abstract Result decode(RecordView record, JsonLikeOperations ops); + } + + public static JsonCodec join( + RecordCodec arg1, + RecordCodec arg2, + Tuple.Func2 joiner + ) { + return new RecordCompleteCodec<>() { + + @Override + public Result encode(O data, JsonLikeOperations ops) { + return Stream.of(arg1.enc(data, ops), arg2.enc(data, ops)) + .reduce(Result.ok(ops.createObject()), RecordCodec::merge) + .map(RecordBuilder::complete); + } + + @Override + public Result decode(RecordView format, JsonLikeOperations ops) { + return Tuple.Tuple2.collect(new Tuple.Tuple2<>(arg1, arg2) + .map(it -> it.dec(format, ops), it -> it.dec(format, ops))) + .map(it -> it.applyTo(joiner)); + } + }; + } +} diff --git a/src/main/java/moe/nea/pcj/json/RecordView.java b/src/main/java/moe/nea/pcj/json/RecordView.java new file mode 100644 index 0000000..968a936 --- /dev/null +++ b/src/main/java/moe/nea/pcj/json/RecordView.java @@ -0,0 +1,10 @@ +package moe.nea.pcj.json; + +import java.util.Collection; +import java.util.Optional; + +public interface RecordView { + Collection getKeys(); + + Optional get(String key); +} diff --git a/src/main/java/moe/nea/pcj/json/UnexpectedJsonElement.java b/src/main/java/moe/nea/pcj/json/UnexpectedJsonElement.java new file mode 100644 index 0000000..7bee7c1 --- /dev/null +++ b/src/main/java/moe/nea/pcj/json/UnexpectedJsonElement.java @@ -0,0 +1,7 @@ +package moe.nea.pcj.json; + +public record UnexpectedJsonElement( + String expectedType, + Object actualJsonObject +) implements JsonLikeError { +} diff --git a/src/main/java/moe/nea/pcj/json/package-info.java b/src/main/java/moe/nea/pcj/json/package-info.java new file mode 100644 index 0000000..a5aace0 --- /dev/null +++ b/src/main/java/moe/nea/pcj/json/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package moe.nea.pcj.json; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file -- cgit