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

com.codepoetics.octarine.json.deserialisation.RecordDeserialiser Maven / Gradle / Ivy

There is a newer version: 0.18
Show newest version
package com.codepoetics.octarine.json.deserialisation;

import com.codepoetics.octarine.records.Key;
import com.codepoetics.octarine.records.Record;
import com.codepoetics.octarine.records.Value;
import com.codepoetics.octarine.records.Schema;
import com.codepoetics.octarine.records.Valid;
import com.codepoetics.octarine.records.Validation;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import org.pcollections.PMap;
import org.pcollections.PVector;

import java.io.IOException;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

public final class RecordDeserialiser implements SafeDeserialiser {

    public static Builder builder() {
        return new Builder();
    }

    public static final class Builder implements Supplier {

        private final Map> valueReaders = new HashMap<>();

        Builder() {
        }

        @Override
        public RecordDeserialiser get() {
            return new RecordDeserialiser((fieldName, parser) ->
                    Optional.ofNullable(valueReaders.get(fieldName)).map(r -> r.apply(parser)));
        }

        public  Builder read(Key key, Function deserialiser) {
            return read(key, key.name(), deserialiser);
        }

        public  Builder read(Key key, String fieldName, Function deserialiser) {
            valueReaders.put(fieldName, p -> key.of(deserialiser.apply(p)));
            return this;
        }

        public  Builder read(Key key, Supplier> deserialiserSupplier) {
            return read(key, deserialiserSupplier.get());
        }

        public  Builder read(Key key, String fieldName, Supplier> deserialiserSupplier) {
            return read(key, fieldName, deserialiserSupplier.get());
        }

        public Builder readString(Key key) {
            return read(key, Deserialisers.ofString);
        }

        public  Builder readFromString(Key key, Function converter) {
            return read(key, Deserialisers.ofString.andThen(converter));
        }

        public Builder readInteger(Key key) {
            return read(key, Deserialisers.ofInteger);
        }

        public Builder readDouble(Key key) {
            return read(key, Deserialisers.ofDouble);
        }

        public Builder readBoolean(Key key) {
            return read(key, Deserialisers.ofBoolean);
        }

        public Builder readLong(Key key) {
            return read(key, Deserialisers.ofLong);
        }

        public  Builder readList(Key> key, Function deserialiser) {
            return read(key, ListDeserialiser.readingItemsWith(deserialiser));
        }

        public  Builder readMap(Key> key, Function deserialiser) {
            return read(key, MapDeserialiser.readingValuesWith(deserialiser));
        }

        public  Builder readValidRecord(Key> key, Function> deserialiser) {
            return read(key, Deserialisers.ofValid(deserialiser));
        }

        public Builder readString(Key key, String fieldName) {
            return read(key, fieldName, Deserialisers.ofString);
        }

        public  Builder readFromString(Key key, String fieldName, Function converter) {
            return read(key, fieldName, Deserialisers.ofString.andThen(converter));
        }

        public Builder readInteger(Key key, String fieldName) {
            return read(key, fieldName, Deserialisers.ofInteger);
        }

        public Builder readDouble(Key key, String fieldName) {
            return read(key, fieldName, Deserialisers.ofDouble);
        }

        public Builder readBoolean(Key key, String fieldName) {
            return read(key, fieldName, Deserialisers.ofBoolean);
        }

        public Builder readLong(Key key, String fieldName) {
            return read(key, fieldName, Deserialisers.ofLong);
        }

        public  Builder readList(Key> key, String fieldName, Function deserialiser) {
            return read(key, fieldName, ListDeserialiser.readingItemsWith(deserialiser));
        }

        public  Builder readMap(Key> key, String fieldName, Function deserialiser) {
            return read(key, fieldName, MapDeserialiser.readingValuesWith(deserialiser));
        }

        public  Builder readValidRecord(Key> key, String fieldName, Function> deserialiser) {
            return read(key, fieldName, Deserialisers.ofValid(deserialiser));
        }
    }

    private final BiFunction> parserMapper;

    private RecordDeserialiser(BiFunction> parserMapper) {
        this.parserMapper = parserMapper;
    }

    @Override
    public Record applyUnsafe(JsonParser parser) throws IOException {
        List values = new ArrayList<>();

        if (parser.nextToken() == JsonToken.END_OBJECT) {
            return Record.empty();
        }

        while (parser.nextValue() != JsonToken.END_OBJECT) {
            String fieldName = parser.getCurrentName();
            parserMapper.apply(fieldName, parser).ifPresent(values::add);
        }

        return Record.of(values);
    }

    public  Deserialiser> validAgainst(Schema schema) {
        return new ValidRecordDeserialiser<>(schema, this);
    }

}