package net.minecraft.world.item; import com.mojang.datafixers.util.Either; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import java.util.Optional; import java.util.function.Function; import net.minecraft.core.Holder; import net.minecraft.core.HolderLookup; import net.minecraft.core.Registry; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceKey; public record EitherHolder(Either, ResourceKey> contents) { public EitherHolder(Holder holder) { this(Either.left(holder)); } public EitherHolder(ResourceKey key) { this(Either.right(key)); } public static Codec> codec(ResourceKey> registryKey, Codec> codec) { return Codec.either( codec, ResourceKey.codec(registryKey).comapFlatMap(resourceKey -> DataResult.error(() -> "Cannot parse as key without registry"), Function.identity()) ) .xmap(EitherHolder::new, EitherHolder::contents); } public static StreamCodec> streamCodec( ResourceKey> registryKey, StreamCodec> streamCodec ) { return StreamCodec.composite(ByteBufCodecs.either(streamCodec, ResourceKey.streamCodec(registryKey)), EitherHolder::contents, EitherHolder::new); } public Optional unwrap(Registry registry) { return this.contents.map(holder -> Optional.of(holder.value()), registry::getOptional); } public Optional> unwrap(HolderLookup.Provider registries) { return this.contents.map(Optional::of, resourceKey -> registries.get(resourceKey).map(reference -> reference)); } public Optional> key() { return this.contents.map(Holder::unwrapKey, Optional::of); } }