package io.gitlab.jfronny.muscript.json; import io.gitlab.jfronny.commons.serialize.SerializeReader; import io.gitlab.jfronny.commons.serialize.SerializeWriter; import io.gitlab.jfronny.commons.serialize.Transport; import io.gitlab.jfronny.commons.serialize.databind.DatabindSerializer; import io.gitlab.jfronny.commons.serialize.databind.ObjectMapper; import io.gitlab.jfronny.muscript.data.additional.DFinal; import io.gitlab.jfronny.muscript.data.additional.context.Scope; import io.gitlab.jfronny.muscript.data.additional.libs.IntentionalException; import io.gitlab.jfronny.muscript.data.dynamic.DList; import io.gitlab.jfronny.muscript.data.dynamic.DString; import io.gitlab.jfronny.muscript.data.dynamic.Dynamic; import io.gitlab.jfronny.muscript.data.dynamic.type.DType; import java.io.IOException; import static io.gitlab.jfronny.muscript.data.dynamic.type.DSL.*; import static io.gitlab.jfronny.muscript.data.dynamic.type.DSL.BOOL; public class TransportLib, Writer extends SerializeWriter> { private final DatabindSerializer lenientBackend; private final DatabindSerializer strictBackend; private final String serializeName; private final String deserializeName; public TransportLib(Transport lenientTransport, Transport strictTransport, String serializeName, String deserializeName) { ObjectMapper mapper = new ObjectMapper(); this.lenientBackend = new DatabindSerializer<>(lenientTransport, mapper); this.strictBackend = new DatabindSerializer<>(strictTransport, mapper); this.serializeName = serializeName; this.deserializeName = deserializeName; } public Scope addTo(Scope scope) { return scope .set(serializeName, serialize, this::serialize) .set(deserializeName, deserialize, this::deserialize); } private final DType serialize = callable(STRING, arg("value", generic(0))) .and(callable(STRING, arg("value", generic(0)), arg("lenient", BOOL))); public DString serialize(DList args) { if (args.isEmpty() || args.size() > 2) throw new IllegalArgumentException("Invalid number of arguments for toJson: expected 1 or 2 but got " + args.size()); Dynamic source = args.get(0); boolean lenient = args.size() > 1 && args.get(1).asBool().getValue(); try { return DFinal.of((lenient ? lenientBackend : strictBackend).serialize(source)); } catch (IOException e) { throw new IntentionalException("Could not serialize value: " + e.getMessage()); } } private final DType deserialize = callable(generic(0), arg("source", STRING)) .and(callable(generic(0), arg("source", STRING), arg("lenient", BOOL))); public Dynamic deserialize(DList args) { if (args.isEmpty() || args.size() > 2) throw new IllegalArgumentException("Invalid number of arguments for fromJson: expected 1 or 2 but got " + args.size()); String source = args.get(0).asString().getValue(); boolean lenient = args.size() > 1 && args.get(1).asBool().getValue(); try { return (lenient ? lenientBackend : strictBackend).deserialize(source, Dynamic.class); } catch (IOException e) { throw new IntentionalException("Could not deserialize value: " + e.getMessage()); } } }