diff --git a/src/main/java/com/mojang/datafixers/util/Tuple.java b/src/main/java/com/mojang/datafixers/util/Tuple.java new file mode 100644 index 00000000..f5e92ac6 --- /dev/null +++ b/src/main/java/com/mojang/datafixers/util/Tuple.java @@ -0,0 +1,189 @@ +package com.mojang.datafixers.util; + +import java.util.List; + +/** + * The Tuple interface defines a finite-length tuple that allows for storing multiple values of different types.
+ * It provides a series of static factory methods to create tuple instances of different lengths (from 2 to 16 elements).
+ * Tuple instances can be converted to a list form using the asList method.
+ * Example: + *
{@code
+ *     Tuple.of(1, 2) // Tuple.T2
+ * }
+ * + * @author TT432 + */ +public sealed interface Tuple permits Tuple.T10, Tuple.T11, Tuple.T12, Tuple.T13, Tuple.T14, Tuple.T15, Tuple.T16, Tuple.T2, Tuple.T3, Tuple.T4, Tuple.T5, Tuple.T6, Tuple.T7, Tuple.T8, Tuple.T9 { + List asList(); + + static T2 of(A a, B b) { + return new T2<>(a, b); + } + + static T3 of(A a, B b, C c) { + return new T3<>(a, b, c); + } + + static T4 of(A a, B b, C c, D d) { + return new T4<>(a, b, c, d); + } + + static T5 of(A a, B b, C c, D d, E e) { + return new T5<>(a, b, c, d, e); + } + + static T6 of(A a, B b, C c, D d, E e, F f) { + return new T6<>(a, b, c, d, e, f); + } + + static T7 of(A a, B b, C c, D d, E e, F f, G g) { + return new T7<>(a, b, c, d, e, f, g); + } + + static T8 of(A a, B b, C c, D d, E e, F f, G g, H h) { + return new T8<>(a, b, c, d, e, f, g, h); + } + + static T9 of(A a, B b, C c, D d, E e, F f, G g, H h, I i) { + return new T9<>(a, b, c, d, e, f, g, h, i); + } + + static T10 of(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) { + return new T10<>(a, b, c, d, e, f, g, h, i, j); + } + + static T11 of(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k) { + return new T11<>(a, b, c, d, e, f, g, h, i, j, k); + } + + static T12 of(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l) { + return new T12<>(a, b, c, d, e, f, g, h, i, j, k, l); + } + + static T13 of(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m) { + return new T13<>(a, b, c, d, e, f, g, h, i, j, k, l, m); + } + + static T14 of(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m, N n) { + return new T14<>(a, b, c, d, e, f, g, h, i, j, k, l, m, n); + } + + static T15 of(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m, N n, O o) { + return new T15<>(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o); + } + + static T16 of(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m, N n, O o, P p) { + return new T16<>(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p); + } + + record T2(A a, B b) implements Tuple { + @Override + public List asList() { + return List.of(a, b); + } + } + + record T3(A a, B b, C c) implements Tuple { + @Override + public List asList() { + return List.of(a, b, c); + } + } + + record T4(A a, B b, C c, D d) implements Tuple { + @Override + public List asList() { + return List.of(a, b, c, d); + } + } + + record T5(A a, B b, C c, D d, E e) implements Tuple { + @Override + public List asList() { + return List.of(a, b, c, d, e); + } + } + + record T6(A a, B b, C c, D d, E e, F f) implements Tuple { + @Override + public List asList() { + return List.of(a, b, c, d, e, f); + } + } + + record T7(A a, B b, C c, D d, E e, F f, G g) implements Tuple { + @Override + public List asList() { + return List.of(a, b, c, d, e, f, g); + } + } + + record T8(A a, B b, C c, D d, E e, F f, G g, H h) implements Tuple { + @Override + public List asList() { + return List.of(a, b, c, d, e, f, g, h); + } + } + + record T9(A a, B b, C c, D d, E e, F f, G g, H h, I i) implements Tuple { + @Override + public List asList() { + return List.of(a, b, c, d, e, f, g, h, i); + } + } + + record T10(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) implements Tuple { + @Override + public List asList() { + return List.of(a, b, c, d, e, f, g, h, i, j); + } + } + + record T11(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, + K k) implements Tuple { + @Override + public List asList() { + return List.of(a, b, c, d, e, f, g, h, i, j, k); + } + } + + record T12(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, + L l) implements Tuple { + @Override + public List asList() { + return List.of(a, b, c, d, e, f, g, h, i, j, k, l); + } + } + + record T13(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, + M m) implements Tuple { + @Override + public List asList() { + return List.of(a, b, c, d, e, f, g, h, i, j, k, l, m); + } + } + + record T14(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, + M m, N n) implements Tuple { + @Override + public List asList() { + return List.of(a, b, c, d, e, f, g, h, i, j, k, l, m, n); + } + } + + record T15(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, + M m, N n, O o) implements Tuple { + @Override + public List asList() { + return List.of(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o); + } + } + + record T16(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, + L l, M m, N n, O o, P p) implements Tuple { + @Override + public List asList() { + return List.of(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p); + } + } +} diff --git a/src/main/java/com/mojang/serialization/codecs/TupleCodec.java b/src/main/java/com/mojang/serialization/codecs/TupleCodec.java new file mode 100644 index 00000000..69e27f6a --- /dev/null +++ b/src/main/java/com/mojang/serialization/codecs/TupleCodec.java @@ -0,0 +1,433 @@ +package com.mojang.serialization.codecs; + +import com.mojang.datafixers.util.*; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.DynamicOps; +import com.mojang.serialization.ListBuilder; +import com.mojang.datafixers.util.Tuple.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Stream; + +/** + * The TupleCodec class provides a heterogeneous list akin to how Tuple relates to List in a similar way Object does to Map.
+ * Example: + *
{@code
+ *      var codec = TupleCodec.tuple(Codec.INT, Codec.FLOAT); // T2Codec
+ *      codec.decode("[1, 2.0]"); // Decodes to List(1, 2.0)
+ * }
+ * @author TT432 + */ +@SuppressWarnings({"unchecked", "rawtypes", "unused"}) +public sealed interface TupleCodec extends Codec> { + List> getCodecs(); + + static T1Codec tuple(Codec codec1) { + return new T1Codec<>(codec1); + } + + static T2Codec tuple(Codec codec1, Codec codec2) { + return new T2Codec<>(codec1, codec2); + } + + static T3Codec tuple(Codec codec1, Codec codec2, Codec codec3) { + return new T3Codec<>(codec1, codec2, codec3); + } + + static T4Codec tuple(Codec codec1, Codec codec2, Codec codec3, Codec codec4) { + return new T4Codec<>(codec1, codec2, codec3, codec4); + } + + static T5Codec tuple(Codec codec1, Codec codec2, Codec codec3, Codec codec4, Codec codec5) { + return new T5Codec<>(codec1, codec2, codec3, codec4, codec5); + } + + static T6Codec tuple(Codec codec1, Codec codec2, Codec codec3, Codec codec4, Codec codec5, Codec codec6) { + return new T6Codec<>(codec1, codec2, codec3, codec4, codec5, codec6); + } + + static T7Codec tuple(Codec codec1, Codec codec2, Codec codec3, Codec codec4, Codec codec5, Codec codec6, Codec codec7) { + return new T7Codec<>(codec1, codec2, codec3, codec4, codec5, codec6, codec7); + } + + static T8Codec tuple(Codec codec1, Codec codec2, Codec codec3, Codec codec4, Codec codec5, Codec codec6, Codec codec7, Codec codec8) { + return new T8Codec<>(codec1, codec2, codec3, codec4, codec5, codec6, codec7, codec8); + } + + static T9Codec tuple(Codec codec1, Codec codec2, Codec codec3, Codec codec4, Codec codec5, Codec codec6, Codec codec7, Codec codec8, Codec codec9) { + return new T9Codec<>(codec1, codec2, codec3, codec4, codec5, codec6, codec7, codec8, codec9); + } + + static T10Codec tuple(Codec codec1, Codec codec2, Codec codec3, Codec codec4, Codec codec5, Codec codec6, Codec codec7, Codec codec8, Codec codec9, Codec codec10) { + return new T10Codec<>(codec1, codec2, codec3, codec4, codec5, codec6, codec7, codec8, codec9, codec10); + } + + static T11Codec tuple(Codec codec1, Codec codec2, Codec codec3, Codec codec4, Codec codec5, Codec codec6, Codec codec7, Codec codec8, Codec codec9, Codec codec10, Codec codec11) { + return new T11Codec<>(codec1, codec2, codec3, codec4, codec5, codec6, codec7, codec8, codec9, codec10, codec11); + } + + static T12Codec tuple(Codec codec1, Codec codec2, Codec codec3, Codec codec4, Codec codec5, Codec codec6, Codec codec7, Codec codec8, Codec codec9, Codec codec10, Codec codec11, Codec codec12) { + return new T12Codec<>(codec1, codec2, codec3, codec4, codec5, codec6, codec7, codec8, codec9, codec10, codec11, codec12); + } + + static T13Codec tuple(Codec codec1, Codec codec2, Codec codec3, Codec codec4, Codec codec5, Codec codec6, Codec codec7, Codec codec8, Codec codec9, Codec codec10, Codec codec11, Codec codec12, Codec codec13) { + return new T13Codec<>(codec1, codec2, codec3, codec4, codec5, codec6, codec7, codec8, codec9, codec10, codec11, codec12, codec13); + } + + static T14Codec tuple(Codec codec1, Codec codec2, Codec codec3, Codec codec4, Codec codec5, Codec codec6, Codec codec7, Codec codec8, Codec codec9, Codec codec10, Codec codec11, Codec codec12, Codec codec13, Codec codec14) { + return new T14Codec<>(codec1, codec2, codec3, codec4, codec5, codec6, codec7, codec8, codec9, codec10, codec11, codec12, codec13, codec14); + } + + static T15Codec tuple(Codec codec1, Codec codec2, Codec codec3, Codec codec4, Codec codec5, Codec codec6, Codec codec7, Codec codec8, Codec codec9, Codec codec10, Codec codec11, Codec codec12, Codec codec13, Codec codec14, Codec codec15) { + return new T15Codec<>(codec1, codec2, codec3, codec4, codec5, codec6, codec7, codec8, codec9, codec10, codec11, codec12, codec13, codec14, codec15); + } + + static T16Codec tuple(Codec codec1, Codec codec2, Codec codec3, Codec codec4, Codec codec5, Codec codec6, Codec codec7, Codec codec8, Codec codec9, Codec codec10, Codec codec11, Codec codec12, Codec codec13, Codec codec14, Codec codec15, Codec

codec16) { + return new T16Codec<>(codec1, codec2, codec3, codec4, codec5, codec6, codec7, codec8, codec9, codec10, codec11, codec12, codec13, codec14, codec15, codec16); + } + + @Override + default DataResult, T>> decode(DynamicOps ops, T input) { + DataResult> stream = ops.getStream(input); + return stream.error() + ., T>>>map(streamPartialResult -> + DataResult.error(streamPartialResult::message)) + .orElse(stream.result()., T>>>map(s -> { + List> codecs = getCodecs(); + List list = s.toList(); + + if (list.size() != codecs.size()) { + return DataResult.error(() -> "can't process as " + this + ", size not equals."); + } + + List result = new ArrayList<>(); + + for (int i = 0; i < codecs.size(); i++) { + var decode = codecs.get(i).decode(ops, list.get(i)).get().mapBoth(Pair::getFirst, Function.identity()); + + decode.ifLeft(result::add); + + var right = decode.right(); + + if (right.isPresent()) { + return DataResult.error(() -> this + " error: " + right.get().message()); + } + } + + return DataResult.success(Pair.of(result, input)); + }).orElse(DataResult.error(() -> this + " can't parse as list."))); + } + + @Override + default DataResult encode(List input, DynamicOps ops, T prefix) { + List> codecs = getCodecs(); + + if (input.size() != codecs.size()) + return DataResult.error(() -> "can't encode " + this + ", because input array size not equals this."); + + final ListBuilder builder = ops.listBuilder(); + + for (int i = 0; i < input.size(); i++) { + builder.add(((Codec) codecs.get(i)).encodeStart(ops, input.get(i))); + } + + return builder.build(prefix); + } + + record T1Codec(Codec codec) implements TupleCodec { + @Override + public List> getCodecs() { + return List.of(codec); + } + + public Codec bmap(Function to, Function from) { + return xmap(l -> to.apply((A) l.get(0)), from.andThen(List::of)); + } + + @Override + public String toString() { + return "Tuple1[" + codec + "]"; + } + } + + record T2Codec(Codec codec1, Codec codec2) implements TupleCodec { + @Override + public List> getCodecs() { + return List.of(codec1, codec2); + } + + public Codec bmap(BiFunction to, Function> from) { + return xmap(l -> to.apply((A) l.get(0), (B) l.get(1)), from.andThen(Tuple::asList)); + } + + @Override + public String toString() { + return "Tuple2[" + codec1 + ", " + codec2 + "]"; + } + } + + record T3Codec(Codec codec1, Codec codec2, Codec codec3) implements TupleCodec { + @Override + public List> getCodecs() { + return List.of(codec1, codec2, codec3); + } + + public Codec bmap(Function3 to, Function> from) { + return xmap(l -> to.apply((A) l.get(0), (B) l.get(1), (C) l.get(2)), from.andThen(Tuple::asList)); + } + + @Override + public String toString() { + return "Tuple3[" + codec1 + ", " + codec2 + ", " + codec3 + "]"; + } + } + + record T4Codec(Codec codec1, Codec codec2, Codec codec3, + Codec codec4) implements TupleCodec { + @Override + public List> getCodecs() { + return List.of(codec1, codec2, codec3, codec4); + } + + public Codec bmap(Function4 to, Function> from) { + return xmap(l -> to.apply((A) l.get(0), (B) l.get(1), (C) l.get(2), (D) l.get(3)), from.andThen(Tuple::asList)); + } + + @Override + public String toString() { + return "Tuple4[" + codec1 + ", " + codec2 + ", " + codec3 + ", " + codec4 + "]"; + } + } + + record T5Codec(Codec codec1, Codec codec2, Codec codec3, Codec codec4, + Codec codec5) implements TupleCodec { + @Override + public List> getCodecs() { + return List.of(codec1, codec2, codec3, codec4, codec5); + } + + public Codec bmap(Function5 to, Function> from) { + return xmap(l -> to.apply((A) l.get(0), (B) l.get(1), (C) l.get(2), (D) l.get(3), (E) l.get(4)), from.andThen(Tuple::asList)); + } + + @Override + public String toString() { + return "Tuple5[" + codec1 + ", " + codec2 + ", " + codec3 + ", " + codec4 + ", " + codec5 + "]"; + } + } + + record T6Codec(Codec codec1, Codec codec2, Codec codec3, Codec codec4, + Codec codec5, Codec codec6) implements TupleCodec { + @Override + public List> getCodecs() { + return List.of(codec1, codec2, codec3, codec4, codec5, codec6); + } + + public Codec bmap(Function6 to, Function> from) { + return xmap(l -> to.apply((A) l.get(0), (B) l.get(1), (C) l.get(2), (D) l.get(3), (E) l.get(4), (F) l.get(5)), from.andThen(Tuple::asList)); + } + + @Override + public String toString() { + return "Tuple6[" + codec1 + ", " + codec2 + ", " + codec3 + ", " + codec4 + ", " + codec5 + ", " + codec6 + "]"; + } + } + + record T7Codec(Codec codec1, Codec codec2, Codec codec3, Codec codec4, + Codec codec5, Codec codec6, Codec codec7) implements TupleCodec { + @Override + public List> getCodecs() { + return List.of(codec1, codec2, codec3, codec4, codec5, codec6, codec7); + } + + public Codec bmap(Function7 to, Function> from) { + return xmap(l -> to.apply((A) l.get(0), (B) l.get(1), (C) l.get(2), (D) l.get(3), (E) l.get(4), (F) l.get(5), (G) l.get(6)), from.andThen(Tuple::asList)); + } + + @Override + public String toString() { + return "Tuple7[" + codec1 + ", " + codec2 + ", " + codec3 + ", " + codec4 + ", " + codec5 + ", " + codec6 + ", " + codec7 + "]"; + } + } + + record T8Codec(Codec codec1, Codec codec2, Codec codec3, Codec codec4, + Codec codec5, Codec codec6, Codec codec7, + Codec codec8) implements TupleCodec { + @Override + public List> getCodecs() { + return List.of(codec1, codec2, codec3, codec4, codec5, codec6, codec7, codec8); + } + + public Codec bmap(Function8 to, Function> from) { + return xmap(l -> to.apply((A) l.get(0), (B) l.get(1), (C) l.get(2), (D) l.get(3), (E) l.get(4), (F) l.get(5), (G) l.get(6), (H) l.get(7)), from.andThen(Tuple::asList)); + } + + @Override + public String toString() { + return "Tuple8[" + codec1 + ", " + codec2 + ", " + codec3 + ", " + codec4 + ", " + codec5 + ", " + codec6 + ", " + codec7 + ", " + codec8 + "]"; + } + } + + record T9Codec(Codec codec1, Codec codec2, Codec codec3, Codec codec4, + Codec codec5, Codec codec6, Codec codec7, Codec codec8, + Codec codec9) implements TupleCodec { + @Override + public List> getCodecs() { + return List.of(codec1, codec2, codec3, codec4, codec5, codec6, codec7, codec8, codec9); + } + + public Codec bmap(Function9 to, Function> from) { + return xmap(l -> to.apply((A) l.get(0), (B) l.get(1), (C) l.get(2), (D) l.get(3), (E) l.get(4), (F) l.get(5), (G) l.get(6), (H) l.get(7), (I) l.get(8)), from.andThen(Tuple::asList)); + } + + @Override + public String toString() { + return "Tuple9[" + codec1 + ", " + codec2 + ", " + codec3 + ", " + codec4 + ", " + codec5 + ", " + codec6 + ", " + codec7 + ", " + codec8 + ", " + codec9 + "]"; + } + } + + record T10Codec(Codec codec1, Codec codec2, Codec codec3, Codec codec4, + Codec codec5, Codec codec6, Codec codec7, Codec codec8, + Codec codec9, Codec codec10) implements TupleCodec { + @Override + public List> getCodecs() { + return List.of(codec1, codec2, codec3, codec4, codec5, codec6, codec7, codec8, codec9, codec10); + } + + public Codec bmap(Function10 to, Function> from) { + return xmap(l -> to.apply((A) l.get(0), (B) l.get(1), (C) l.get(2), (D) l.get(3), (E) l.get(4), (F) l.get(5), (G) l.get(6), (H) l.get(7), (I) l.get(8), (J) l.get(9)), from.andThen(Tuple::asList)); + } + + @Override + public String toString() { + return "Tuple10[" + codec1 + ", " + codec2 + ", " + codec3 + ", " + codec4 + ", " + codec5 + ", " + codec6 + ", " + codec7 + ", " + codec8 + ", " + codec9 + ", " + codec10 + "]"; + } + } + + record T11Codec(Codec codec1, Codec codec2, Codec codec3, Codec codec4, + Codec codec5, Codec codec6, Codec codec7, Codec codec8, + Codec codec9, Codec codec10, + Codec codec11) implements TupleCodec { + @Override + public List> getCodecs() { + return List.of(codec1, codec2, codec3, codec4, codec5, codec6, codec7, codec8, codec9, codec10, codec11); + } + + public Codec bmap(Function11 to, Function> from) { + return xmap(l -> to.apply((A) l.get(0), (B) l.get(1), (C) l.get(2), (D) l.get(3), (E) l.get(4), (F) l.get(5), (G) l.get(6), (H) l.get(7), (I) l.get(8), (J) l.get(9), (K) l.get(10)), from.andThen(Tuple::asList)); + } + + @Override + public String toString() { + return "Tuple11[" + codec1 + ", " + codec2 + ", " + codec3 + ", " + codec4 + ", " + codec5 + ", " + codec6 + ", " + codec7 + ", " + codec8 + ", " + codec9 + ", " + codec10 + ", " + codec11 + "]"; + } + } + + record T12Codec(Codec codec1, Codec codec2, Codec codec3, + Codec codec4, Codec codec5, Codec codec6, + Codec codec7, Codec codec8, Codec codec9, + Codec codec10, Codec codec11, + Codec codec12) implements TupleCodec { + @Override + public List> getCodecs() { + return List.of(codec1, codec2, codec3, codec4, codec5, codec6, codec7, codec8, codec9, codec10, codec11, codec12); + } + + public Codec bmap(Function12 to, Function> from) { + return xmap(l -> to.apply((A) l.get(0), (B) l.get(1), (C) l.get(2), (D) l.get(3), (E) l.get(4), (F) l.get(5), (G) l.get(6), (H) l.get(7), (I) l.get(8), (J) l.get(9), (K) l.get(10), (L) l.get(11)), from.andThen(Tuple::asList)); + } + + @Override + public String toString() { + return "Tuple12[" + codec1 + ", " + codec2 + ", " + codec3 + ", " + codec4 + ", " + codec5 + ", " + codec6 + ", " + codec7 + ", " + codec8 + ", " + codec9 + ", " + codec10 + ", " + codec11 + ", " + codec12 + "]"; + } + } + + record T13Codec(Codec codec1, Codec codec2, Codec codec3, + Codec codec4, Codec codec5, Codec codec6, + Codec codec7, Codec codec8, Codec codec9, + Codec codec10, Codec codec11, Codec codec12, + Codec codec13) implements TupleCodec { + @Override + public List> getCodecs() { + return List.of(codec1, codec2, codec3, codec4, codec5, codec6, codec7, codec8, codec9, codec10, codec11, codec12, codec13); + } + + public Codec bmap(Function13 to, Function> from) { + return xmap(l -> to.apply((A) l.get(0), (B) l.get(1), (C) l.get(2), (D) l.get(3), (E) l.get(4), (F) l.get(5), (G) l.get(6), (H) l.get(7), (I) l.get(8), (J) l.get(9), (K) l.get(10), (L) l.get(11), (M) l.get(12)), from.andThen(Tuple::asList)); + } + + @Override + public String toString() { + return "Tuple13[" + codec1 + ", " + codec2 + ", " + codec3 + ", " + codec4 + ", " + codec5 + ", " + codec6 + ", " + codec7 + ", " + codec8 + ", " + codec9 + ", " + codec10 + ", " + codec11 + ", " + codec12 + ", " + codec13 + "]"; + } + } + + record T14Codec(Codec codec1, Codec codec2, Codec codec3, + Codec codec4, Codec codec5, Codec codec6, + Codec codec7, Codec codec8, Codec codec9, + Codec codec10, Codec codec11, Codec codec12, + Codec codec13, + Codec codec14) implements TupleCodec { + @Override + public List> getCodecs() { + return List.of(codec1, codec2, codec3, codec4, codec5, codec6, codec7, codec8, codec9, codec10, codec11, codec12, codec13, codec14); + } + + public Codec bmap(Function14 to, Function> from) { + return xmap(l -> to.apply((A) l.get(0), (B) l.get(1), (C) l.get(2), (D) l.get(3), (E) l.get(4), (F) l.get(5), (G) l.get(6), (H) l.get(7), (I) l.get(8), (J) l.get(9), (K) l.get(10), (L) l.get(11), (M) l.get(12), (N) l.get(13)), from.andThen(Tuple::asList)); + } + + @Override + public String toString() { + return "Tuple14[" + codec1 + ", " + codec2 + ", " + codec3 + ", " + codec4 + ", " + codec5 + ", " + codec6 + ", " + codec7 + ", " + codec8 + ", " + codec9 + ", " + codec10 + ", " + codec11 + ", " + codec12 + ", " + codec13 + ", " + codec14 + "]"; + } + } + + record T15Codec(Codec codec1, Codec codec2, Codec codec3, + Codec codec4, Codec codec5, Codec codec6, + Codec codec7, Codec codec8, Codec codec9, + Codec codec10, Codec codec11, Codec codec12, + Codec codec13, Codec codec14, + Codec codec15) implements TupleCodec { + @Override + public List> getCodecs() { + return List.of(codec1, codec2, codec3, codec4, codec5, codec6, codec7, codec8, codec9, codec10, codec11, codec12, codec13, codec14, codec15); + } + + public Codec bmap(Function15 to, Function> from) { + return xmap(l -> to.apply((A) l.get(0), (B) l.get(1), (C) l.get(2), (D) l.get(3), (E) l.get(4), (F) l.get(5), (G) l.get(6), (H) l.get(7), (I) l.get(8), (J) l.get(9), (K) l.get(10), (L) l.get(11), (M) l.get(12), (N) l.get(13), (O) l.get(14)), from.andThen(Tuple::asList)); + } + + @Override + public String toString() { + return "Tuple15[" + codec1 + ", " + codec2 + ", " + codec3 + ", " + codec4 + ", " + codec5 + ", " + codec6 + ", " + codec7 + ", " + codec8 + ", " + codec9 + ", " + codec10 + ", " + codec11 + ", " + codec12 + ", " + codec13 + ", " + codec14 + ", " + codec15 + "]"; + } + } + + record T16Codec(Codec codec1, Codec codec2, Codec codec3, + Codec codec4, Codec codec5, Codec codec6, + Codec codec7, Codec codec8, Codec codec9, + Codec codec10, Codec codec11, + Codec codec12, Codec codec13, + Codec codec14, Codec codec15, + Codec

codec16) implements TupleCodec { + @Override + public List> getCodecs() { + return List.of(codec1, codec2, codec3, codec4, codec5, codec6, codec7, codec8, codec9, codec10, codec11, codec12, codec13, codec14, codec15, codec16); + } + + public Codec bmap(Function16 to, Function> from) { + return xmap(l -> to.apply((A) l.get(0), (B) l.get(1), (C) l.get(2), (D) l.get(3), (E) l.get(4), (F) l.get(5), (G) l.get(6), (H) l.get(7), (I) l.get(8), (J) l.get(9), (K) l.get(10), (L) l.get(11), (M) l.get(12), (N) l.get(13), (O) l.get(14), (P) l.get(15)), from.andThen(Tuple::asList)); + } + + @Override + public String toString() { + return "Tuple16[" + codec1 + ", " + codec2 + ", " + codec3 + ", " + codec4 + ", " + codec5 + ", " + codec6 + ", " + codec7 + ", " + codec8 + ", " + codec9 + ", " + codec10 + ", " + codec11 + ", " + codec12 + ", " + codec13 + ", " + codec14 + ", " + codec15 + ", " + codec16 + "]"; + } + } +}