diff --git a/module.codec/src/main/java/dev/anvilcraft/lib/v2/codec/CodecUtil.java b/module.codec/src/main/java/dev/anvilcraft/lib/v2/codec/CodecUtil.java index df9357f2..811016e6 100644 --- a/module.codec/src/main/java/dev/anvilcraft/lib/v2/codec/CodecUtil.java +++ b/module.codec/src/main/java/dev/anvilcraft/lib/v2/codec/CodecUtil.java @@ -42,6 +42,7 @@ import net.minecraft.world.level.storage.loot.providers.number.NumberProvider; import net.minecraft.world.level.storage.loot.providers.number.NumberProviders; +import java.util.Collections; import java.util.Deque; import java.util.LinkedList; import java.util.List; @@ -359,6 +360,27 @@ public static > MapCodec appendBlockStatePro ).xmap(pair -> pair.getFirst().setValue(property, pair.getSecond().value()), state -> Pair.of(state, property.value(state))); } + /// 构建一个 `ZOM列表`(零/一/多元素列表)MapCodec + /// + /// @param codec 元素编解码器 + /// @param name 名称 + /// @return `ZOM列表`(零/一/多元素列表)MapCodec + public static MapCodec> zomListMap(Codec codec, String name) { + return Codec.mapEither(codec.optionalFieldOf(name), codec.listOf().fieldOf(name)).xmap( + either -> either.map( + op -> op + .map(Collections::singletonList) + .orElse(List.of()), + Function.identity() + ), + list -> list.size() <= 1 + ? list.isEmpty() + ? Either.left(Optional.empty()) + : Either.left(Optional.of(list.getFirst())) + : Either.right(list) + ); + } + /// 创建 {@link Codec} 的便携方法,对 {@link RecordCodecBuilder#create(Function)} 的代理 /// ///

参考了 {@link net.minecraft.network.codec.StreamCodec#composite(StreamCodec, Function, Function)} 的设计