diff --git a/src/main/java/io/wispforest/owo/serialization/StructEndec.java b/src/main/java/io/wispforest/owo/serialization/StructEndec.java index af41932c..76b645c0 100644 --- a/src/main/java/io/wispforest/owo/serialization/StructEndec.java +++ b/src/main/java/io/wispforest/owo/serialization/StructEndec.java @@ -1,9 +1,22 @@ package io.wispforest.owo.serialization; -import io.wispforest.owo.serialization.endec.StructEndecBuilder; +import com.mojang.serialization.*; +import io.wispforest.owo.serialization.format.edm.EdmDeserializer; +import io.wispforest.owo.serialization.format.edm.EdmElement; +import io.wispforest.owo.serialization.format.edm.EdmOps; +import io.wispforest.owo.serialization.format.edm.EdmSerializer; +import net.minecraft.util.Util; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Stream; /** - * Helper Interface for Structs that do not conform to the {@link StructEndecBuilder} format + * Marker and template interface for all endecs which serialize structs + *

+ * Every such endec should extend this interface to profit from the implementation of {@link #mapCodec()} + * and composability which allows {@link Endec#dispatchedStruct(Function, Function, Endec, String)} to work */ public interface StructEndec extends Endec { @@ -22,4 +35,49 @@ default void encode(Serializer serializer, T value) { default T decode(Deserializer deserializer) { return this.decodeStruct(deserializer.struct()); } + + default MapCodec mapCodec() { + return new MapCodec<>() { + @Override + public Stream keys(DynamicOps ops) { + throw new UnsupportedOperationException("MapCodec generated from StructEndec cannot report keys"); + } + + @Override + public DataResult decode(DynamicOps ops, MapLike input) { + try { + var map = new HashMap>(); + input.entries().forEach(pair -> { + map.put( + Util.getResult( + ops.getStringValue(pair.getFirst()), + s -> new IllegalStateException("Unable to parse key: " + s) + ), + ops.convertTo(EdmOps.INSTANCE, pair.getSecond()) + ); + }); + + return DataResult.success(StructEndec.this.decode(new EdmDeserializer(EdmElement.wrapMap(map)))); + } catch (Exception e) { + return DataResult.error(e::getMessage); + } + } + + @Override + public RecordBuilder encode(T input, DynamicOps ops, RecordBuilder prefix) { + try { + var element = StructEndec.this.encodeFully(EdmSerializer::new, input).>>cast(); + + var result = prefix; + for (var entry : element.entrySet()) { + result = result.add(entry.getKey(), EdmOps.INSTANCE.convertTo(ops, entry.getValue())); + } + + return result; + } catch (Exception e) { + return prefix.withErrorsFrom(DataResult.error(e::getMessage, input)); + } + } + }; + } } diff --git a/src/main/java/io/wispforest/owo/serialization/endec/StructEndecBuilder.java b/src/main/java/io/wispforest/owo/serialization/endec/StructEndecBuilder.java index f093e7fc..67b26f0e 100644 --- a/src/main/java/io/wispforest/owo/serialization/endec/StructEndecBuilder.java +++ b/src/main/java/io/wispforest/owo/serialization/endec/StructEndecBuilder.java @@ -2,7 +2,6 @@ import com.mojang.datafixers.util.*; import io.wispforest.owo.serialization.Deserializer; -import io.wispforest.owo.serialization.Endec; import io.wispforest.owo.serialization.Serializer; import io.wispforest.owo.serialization.StructEndec; @@ -12,7 +11,7 @@ // An autogenerated beauty public class StructEndecBuilder { - public static Endec of(StructField f1, Function constructor) { + public static StructEndec of(StructField f1, Function constructor) { return new StructEndec<>() { @Override public void encodeStruct(Serializer.Struct struct, S value) { @@ -26,7 +25,7 @@ public S decodeStruct(Deserializer.Struct struct) { }; } - public static Endec of(StructField f1, StructField f2, BiFunction constructor) { + public static StructEndec of(StructField f1, StructField f2, BiFunction constructor) { return new StructEndec<>() { @Override public void encodeStruct(Serializer.Struct struct, S value) { @@ -42,7 +41,7 @@ public S decodeStruct(Deserializer.Struct struct) { }; } - public static Endec of(StructField f1, StructField f2, StructField f3, Function3 constructor) { + public static StructEndec of(StructField f1, StructField f2, StructField f3, Function3 constructor) { return new StructEndec<>() { @Override public void encodeStruct(Serializer.Struct struct, S value) { @@ -60,7 +59,7 @@ public S decodeStruct(Deserializer.Struct struct) { }; } - public static Endec of(StructField f1, StructField f2, StructField f3, StructField f4, Function4 constructor) { + public static StructEndec of(StructField f1, StructField f2, StructField f3, StructField f4, Function4 constructor) { return new StructEndec<>() { @Override public void encodeStruct(Serializer.Struct struct, S value) { @@ -80,7 +79,7 @@ public S decodeStruct(Deserializer.Struct struct) { }; } - public static Endec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, Function5 constructor) { + public static StructEndec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, Function5 constructor) { return new StructEndec<>() { @Override public void encodeStruct(Serializer.Struct struct, S value) { @@ -102,7 +101,7 @@ public S decodeStruct(Deserializer.Struct struct) { }; } - public static Endec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, Function6 constructor) { + public static StructEndec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, Function6 constructor) { return new StructEndec<>() { @Override public void encodeStruct(Serializer.Struct struct, S value) { @@ -126,7 +125,7 @@ public S decodeStruct(Deserializer.Struct struct) { }; } - public static Endec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, Function7 constructor) { + public static StructEndec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, Function7 constructor) { return new StructEndec<>() { @Override public void encodeStruct(Serializer.Struct struct, S value) { @@ -152,7 +151,7 @@ public S decodeStruct(Deserializer.Struct struct) { }; } - public static Endec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, Function8 constructor) { + public static StructEndec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, Function8 constructor) { return new StructEndec<>() { @Override public void encodeStruct(Serializer.Struct struct, S value) { @@ -180,7 +179,7 @@ public S decodeStruct(Deserializer.Struct struct) { }; } - public static Endec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, StructField f9, Function9 constructor) { + public static StructEndec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, StructField f9, Function9 constructor) { return new StructEndec<>() { @Override public void encodeStruct(Serializer.Struct struct, S value) { @@ -210,7 +209,7 @@ public S decodeStruct(Deserializer.Struct struct) { }; } - public static Endec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, StructField f9, StructField f10, Function10 constructor) { + public static StructEndec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, StructField f9, StructField f10, Function10 constructor) { return new StructEndec<>() { @Override public void encodeStruct(Serializer.Struct struct, S value) { @@ -242,7 +241,7 @@ public S decodeStruct(Deserializer.Struct struct) { }; } - public static Endec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, StructField f9, StructField f10, StructField f11, Function11 constructor) { + public static StructEndec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, StructField f9, StructField f10, StructField f11, Function11 constructor) { return new StructEndec<>() { @Override public void encodeStruct(Serializer.Struct struct, S value) { @@ -276,7 +275,7 @@ public S decodeStruct(Deserializer.Struct struct) { }; } - public static Endec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, StructField f9, StructField f10, StructField f11, StructField f12, Function12 constructor) { + public static StructEndec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, StructField f9, StructField f10, StructField f11, StructField f12, Function12 constructor) { return new StructEndec<>() { @Override public void encodeStruct(Serializer.Struct struct, S value) { @@ -312,7 +311,7 @@ public S decodeStruct(Deserializer.Struct struct) { }; } - public static Endec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, StructField f9, StructField f10, StructField f11, StructField f12, StructField f13, Function13 constructor) { + public static StructEndec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, StructField f9, StructField f10, StructField f11, StructField f12, StructField f13, Function13 constructor) { return new StructEndec<>() { @Override public void encodeStruct(Serializer.Struct struct, S value) { @@ -350,7 +349,7 @@ public S decodeStruct(Deserializer.Struct struct) { }; } - public static Endec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, StructField f9, StructField f10, StructField f11, StructField f12, StructField f13, StructField f14, Function14 constructor) { + public static StructEndec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, StructField f9, StructField f10, StructField f11, StructField f12, StructField f13, StructField f14, Function14 constructor) { return new StructEndec<>() { @Override public void encodeStruct(Serializer.Struct struct, S value) { @@ -390,7 +389,7 @@ public S decodeStruct(Deserializer.Struct struct) { }; } - public static Endec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, StructField f9, StructField f10, StructField f11, StructField f12, StructField f13, StructField f14, StructField f15, Function15 constructor) { + public static StructEndec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, StructField f9, StructField f10, StructField f11, StructField f12, StructField f13, StructField f14, StructField f15, Function15 constructor) { return new StructEndec<>() { @Override public void encodeStruct(Serializer.Struct struct, S value) { @@ -432,7 +431,7 @@ public S decodeStruct(Deserializer.Struct struct) { }; } - public static Endec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, StructField f9, StructField f10, StructField f11, StructField f12, StructField f13, StructField f14, StructField f15, StructField f16, Function16 constructor) { + public static StructEndec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, StructField f9, StructField f10, StructField f11, StructField f12, StructField f13, StructField f14, StructField f15, StructField f16, Function16 constructor) { return new StructEndec<>() { @Override public void encodeStruct(Serializer.Struct struct, S value) { @@ -476,7 +475,7 @@ public S decodeStruct(Deserializer.Struct struct) { }; } - public static Endec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, StructField f9, StructField f10, StructField f11, StructField f12, StructField f13, StructField f14, StructField f15, StructField f16, StructField f17, Function17 constructor) { + public static StructEndec of(StructField f1, StructField f2, StructField f3, StructField f4, StructField f5, StructField f6, StructField f7, StructField f8, StructField f9, StructField f10, StructField f11, StructField f12, StructField f13, StructField f14, StructField f15, StructField f16, StructField f17, Function17 constructor) { return new StructEndec<>() { @Override public void encodeStruct(Serializer.Struct struct, S value) { diff --git a/src/main/java/io/wispforest/owo/text/InsertingTextContent.java b/src/main/java/io/wispforest/owo/text/InsertingTextContent.java index d7761182..bcdedb4b 100644 --- a/src/main/java/io/wispforest/owo/text/InsertingTextContent.java +++ b/src/main/java/io/wispforest/owo/text/InsertingTextContent.java @@ -1,7 +1,7 @@ package io.wispforest.owo.text; -import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; +import io.wispforest.owo.serialization.Endec; +import io.wispforest.owo.serialization.endec.StructEndecBuilder; import net.minecraft.text.StringVisitable; import net.minecraft.text.Style; import net.minecraft.text.Text; @@ -12,9 +12,7 @@ public record InsertingTextContent(int index) implements TextContent { public static final TextContent.Type TYPE = new Type<>( - RecordCodecBuilder.mapCodec( - instance -> instance.group(Codec.INT.fieldOf("index").forGetter(InsertingTextContent::index)).apply(instance, InsertingTextContent::new) - ), + StructEndecBuilder.of(Endec.INT.fieldOf("index", InsertingTextContent::index), InsertingTextContent::new).mapCodec(), "owo:insert" ); diff --git a/src/testmod/java/io/wispforest/uwu/text/BasedTextContent.java b/src/testmod/java/io/wispforest/uwu/text/BasedTextContent.java index 5f887f3c..4b862b0e 100644 --- a/src/testmod/java/io/wispforest/uwu/text/BasedTextContent.java +++ b/src/testmod/java/io/wispforest/uwu/text/BasedTextContent.java @@ -1,7 +1,7 @@ package io.wispforest.uwu.text; -import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; +import io.wispforest.owo.serialization.Endec; +import io.wispforest.owo.serialization.endec.StructEndecBuilder; import net.minecraft.text.StringVisitable; import net.minecraft.text.Style; import net.minecraft.text.TextContent; @@ -10,9 +10,9 @@ public class BasedTextContent implements TextContent { - public static final Type TYPE = new Type<>(RecordCodecBuilder.mapCodec( - instance -> instance.group(Codec.STRING.fieldOf("based").forGetter(o -> o.basedText)).apply(instance, BasedTextContent::new) - ), "uwu:based"); + public static final Type TYPE = new Type<>( + StructEndecBuilder.of(Endec.STRING.fieldOf("based", o -> o.basedText), BasedTextContent::new).mapCodec(), + "uwu:based"); private final String basedText;