All Downloads are FREE. Search and download functionalities are using the official Maven repository.

personthecat.catlib.serialization.codec.EasyMapReader Maven / Gradle / Ivy

Go to download

Utilities for serialization, commands, noise generation, IO, and some new data types.

The newest version!
package personthecat.catlib.serialization.codec;

import com.mojang.datafixers.util.Pair;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.DynamicOps;
import com.mojang.serialization.MapLike;

import javax.annotation.Nullable;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;

@SuppressWarnings("unused")
public class EasyMapReader {

    private final DynamicOps ops;
    private final T prefix;

    public EasyMapReader(final DynamicOps ops, final T prefix) {
        this.ops = ops;
        this.prefix = prefix;
    }

    public  DataResult run(final Function, A> runner) {
        final DataResult> mapResult = this.ops.getMap(this.prefix);
        if (mapResult.error().isPresent()) {
            return DataResult.error(mapResult.error().get().message());
        }
        assert mapResult.result().isPresent();
        final Context ctx = new Context<>(mapResult.result().get(), this.ops, this.prefix);
        try {
            return DataResult.success(runner.apply(ctx));
        } catch (final EasyMapException e) {
            return DataResult.error(e.getMessage());
        }
    }

    public  DataResult> runPaired(final Function, A> runner) {
        return run(ctx -> Pair.of(runner.apply(ctx), this.ops.createList(Stream.empty())));
    }

    public static class Context {
        private final MapLike map;
        private final DynamicOps ops;
        private final T prefix;
        private Class listClass;
        private Class mapClass;

        private Context(final MapLike map, final DynamicOps ops, final T prefix) {
            this.map = map;
            this.ops = ops;
            this.prefix = prefix;
        }

        @Nullable
        public T get(final String key) {
            return this.map.get(key);
        }

        public T mapOrNew(final String key) {
            // Invalid type will be handled later
            final T map = this.map.get(key);
            return map == null ? this.ops.emptyMap() : map;
        }

        public T easyListOrNew(final String key) {
            final T list = this.easyList(key);
            return list == null ? this.ops.emptyList() : list;
        }

        @Nullable
        public T easyList(final String key) {
            final T list = this.map.get(key);
            if (list == null) return null;
            return asOrToList(list);
        }

        private T asOrToList(final T list) {
            if (list.getClass() != this.getListClass()) {
                final T newList = this.ops.emptyList();
                final DataResult result = this.ops.mergeToList(newList, list);
                if (result.error().isPresent()) {
                    throw new EasyMapException("Creating list: " + result.error().get().message());
                }
                assert result.result().isPresent();
                return result.result().get();
            }
            return list;
        }

        public  A readThis(final Codec codec) {
            return this.getOrThrow(codec, this.prefix);
        }

        public boolean readBool(final String key) {
            return this.read(Codec.BOOL, key);
        }

        public boolean readBool(final String key, final Supplier def) {
            return this.read(Codec.BOOL, key, def);
        }

        public double readDouble(final String key) {
            return this.read(Codec.DOUBLE, key);
        }

        public double readDouble(final String key, final Supplier def) {
            return this.read(Codec.DOUBLE, key, def);
        }

        public float readFloat(final String key) {
            return this.read(Codec.FLOAT, key);
        }

        public float readFloat(final String key, final Supplier def) {
            return this.read(Codec.FLOAT, key, def);
        }

        public int readInt(final String key) {
            return this.read(Codec.INT, key);
        }

        public int readInt(final String key, final Supplier def) {
            return this.read(Codec.INT, key, def);
        }

        public String readString(final String key) {
            return this.read(Codec.STRING, key);
        }

        public String readString(final String key, final Supplier def) {
            return this.read(Codec.STRING, key, def);
        }

        public  A read(final Codec codec, final String key) {
            final T t = this.map.get(key);
            if (t == null) throw this.missingValue(key);
            return this.getOrThrow(codec, t);
        }

        public  A read(final Codec codec, final String key, final Supplier def) {
            final T t = this.map.get(key);
            if (t == null) return def.get();
            return this.getOrThrow(codec, t);
        }

        public  Optional readOptional(final Codec codec, final String key) {
            final T t = this.map.get(key);
            if (t == null) return Optional.empty();
            return Optional.of(this.getOrThrow(codec, t));
        }

        public  A error(final String message) {
            throw new EasyMapException(message);
        }

        @SuppressWarnings("unchecked")
        private Class getListClass() {
            if (this.listClass == null) {
                this.listClass = (Class) this.ops.emptyList().getClass();
            }
            return this.listClass;
        }

        @SuppressWarnings("unchecked")
        private Class getMapClass() {
            if (this.mapClass == null) {
                this.mapClass = (Class) this.ops.emptyMap().getClass();
            }
            return this.mapClass;
        }

        private EasyMapException missingValue(final String key) {
            return new EasyMapException("Missing value: " + key);
        }

        private  A getOrThrow(final Codec codec, final T t) {
            return codec.parse(this.ops, t).get().map(Function.identity(), partial -> {
                throw new EasyMapException(partial.message());
            });
        }
    }

    private static class EasyMapException extends RuntimeException {
        EasyMapException(final String msg) {
            super(msg);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy