From 3adcf5b23f435bf9cf0f07f644ddb13eeac842c2 Mon Sep 17 00:00:00 2001 From: Andriy Onyshchuk Date: Tue, 7 Nov 2023 14:03:29 -0800 Subject: [PATCH] add adt example --- .../com/dslplatform/json/adt/JsonArray.java | 12 +++ .../com/dslplatform/json/adt/JsonBoolean.java | 18 ++++ .../com/dslplatform/json/adt/JsonNull.java | 6 ++ .../com/dslplatform/json/adt/JsonNumber.java | 12 +++ .../com/dslplatform/json/adt/JsonObject.java | 24 ++++++ .../com/dslplatform/json/adt/JsonString.java | 12 +++ .../com/dslplatform/json/adt/JsonValue.java | 5 ++ .../json/adt/JsonValueConverter.java | 83 +++++++++++++++++++ 8 files changed, 172 insertions(+) create mode 100644 library/src/main/java/com/dslplatform/json/adt/JsonArray.java create mode 100644 library/src/main/java/com/dslplatform/json/adt/JsonBoolean.java create mode 100644 library/src/main/java/com/dslplatform/json/adt/JsonNull.java create mode 100644 library/src/main/java/com/dslplatform/json/adt/JsonNumber.java create mode 100644 library/src/main/java/com/dslplatform/json/adt/JsonObject.java create mode 100644 library/src/main/java/com/dslplatform/json/adt/JsonString.java create mode 100644 library/src/main/java/com/dslplatform/json/adt/JsonValue.java create mode 100644 library/src/main/java/com/dslplatform/json/adt/JsonValueConverter.java diff --git a/library/src/main/java/com/dslplatform/json/adt/JsonArray.java b/library/src/main/java/com/dslplatform/json/adt/JsonArray.java new file mode 100644 index 00000000..457272a7 --- /dev/null +++ b/library/src/main/java/com/dslplatform/json/adt/JsonArray.java @@ -0,0 +1,12 @@ +package com.dslplatform.json.adt; + +// uncomment for java 21 +// public record JsonArray(DslJsonValue[] value) implements JsonValue { } + +public final class JsonArray implements JsonValue { + public final JsonValue[] value; + + public JsonArray(JsonValue[] value) { + this.value = value; + } +} diff --git a/library/src/main/java/com/dslplatform/json/adt/JsonBoolean.java b/library/src/main/java/com/dslplatform/json/adt/JsonBoolean.java new file mode 100644 index 00000000..8392d9f7 --- /dev/null +++ b/library/src/main/java/com/dslplatform/json/adt/JsonBoolean.java @@ -0,0 +1,18 @@ +package com.dslplatform.json.adt; + +// uncomment for java 21 +// public record JsonBoolean(boolean value) implements JsonValue { +// public static final JsonBoolean TRUE = new JsonBoolean(true); +// public static final JsonBoolean FALSE = new JsonBoolean(false); +// } + +public final class JsonBoolean implements JsonValue { + public static final JsonBoolean TRUE = new JsonBoolean(true); + public static final JsonBoolean FALSE = new JsonBoolean(false); + + public final boolean value; + + private JsonBoolean(boolean value) { + this.value = value; + } +} diff --git a/library/src/main/java/com/dslplatform/json/adt/JsonNull.java b/library/src/main/java/com/dslplatform/json/adt/JsonNull.java new file mode 100644 index 00000000..7ce4a274 --- /dev/null +++ b/library/src/main/java/com/dslplatform/json/adt/JsonNull.java @@ -0,0 +1,6 @@ +package com.dslplatform.json.adt; + +public final class JsonNull implements JsonValue { + private JsonNull() {} + public static final JsonNull INSTANCE = new JsonNull(); +} diff --git a/library/src/main/java/com/dslplatform/json/adt/JsonNumber.java b/library/src/main/java/com/dslplatform/json/adt/JsonNumber.java new file mode 100644 index 00000000..7ef1dc1d --- /dev/null +++ b/library/src/main/java/com/dslplatform/json/adt/JsonNumber.java @@ -0,0 +1,12 @@ +package com.dslplatform.json.adt; + +// uncomment for java 21 +// public record JsonNumber(double value) implements JsonValue { } + +public final class JsonNumber implements JsonValue { + public final double value; + + public JsonNumber(double value) { + this.value = value; + } +} diff --git a/library/src/main/java/com/dslplatform/json/adt/JsonObject.java b/library/src/main/java/com/dslplatform/json/adt/JsonObject.java new file mode 100644 index 00000000..448b1543 --- /dev/null +++ b/library/src/main/java/com/dslplatform/json/adt/JsonObject.java @@ -0,0 +1,24 @@ +package com.dslplatform.json.adt; + +// uncomment for java 21 +// public record JsonObject(Entry[] value) implements JsonValue { +// public record Entry(String name, JsonValue value) {} +// } + +public final class JsonObject implements JsonValue { + public final Entry[] value; + + public JsonObject(Entry[] value) { + this.value = value; + } + + public static class Entry { + public final String name; + public final JsonValue value; + + public Entry(String name, JsonValue value) { + this.name = name; + this.value = value; + } + } +} diff --git a/library/src/main/java/com/dslplatform/json/adt/JsonString.java b/library/src/main/java/com/dslplatform/json/adt/JsonString.java new file mode 100644 index 00000000..0b19edcb --- /dev/null +++ b/library/src/main/java/com/dslplatform/json/adt/JsonString.java @@ -0,0 +1,12 @@ +package com.dslplatform.json.adt; + +// uncomment for java 21 +// public record JsonString(String value) implements JsonValue { } + +public final class JsonString implements JsonValue { + public final String value; + + public JsonString(String value) { + this.value = value; + } +} diff --git a/library/src/main/java/com/dslplatform/json/adt/JsonValue.java b/library/src/main/java/com/dslplatform/json/adt/JsonValue.java new file mode 100644 index 00000000..b03210d7 --- /dev/null +++ b/library/src/main/java/com/dslplatform/json/adt/JsonValue.java @@ -0,0 +1,5 @@ +package com.dslplatform.json.adt; + +// uncomment for java 21 +public /*sealed*/ interface JsonValue /*permits DslJsonArray, DslJsonBoolean, JsonNull, DslJsonNumber, DslJsonObject, DslJsonString*/ { +} diff --git a/library/src/main/java/com/dslplatform/json/adt/JsonValueConverter.java b/library/src/main/java/com/dslplatform/json/adt/JsonValueConverter.java new file mode 100644 index 00000000..4506e2f1 --- /dev/null +++ b/library/src/main/java/com/dslplatform/json/adt/JsonValueConverter.java @@ -0,0 +1,83 @@ +package com.dslplatform.json.adt; + +import com.dslplatform.json.*; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; + +@JsonConverter(target = JsonValue.class) +public abstract class JsonValueConverter { + + public static JsonValue read(JsonReader reader) throws IOException { + if (reader.wasNull()) { + return JsonNull.INSTANCE; + } else if (reader.wasTrue()) { + return JsonBoolean.TRUE; + } else if (reader.wasFalse()) { + return JsonBoolean.FALSE; + } else if (reader.last() == '{') { + reader.getNextToken(); + HashMap elements = new HashMap<>(); + while (reader.last() != '}') { + String key = reader.readKey(); + assert reader.getNextToken() == ':'; + elements.put(key, read(reader)); + reader.getNextToken(); + if (reader.last() == ',') reader.getNextToken(); + } + return new JsonObject(elements.entrySet().stream().map(e -> new JsonObject.Entry(e.getKey(), e.getValue())).toArray(JsonObject.Entry[]::new)); + } else if (reader.last() == '[') { + reader.getNextToken(); + ArrayList elements = new ArrayList<>(); + while (reader.last() != ']') { + elements.add(read(reader)); + reader.getNextToken(); + if (reader.last() == ',') reader.getNextToken(); + } + return new JsonArray(elements.toArray(new JsonValue[0])); + } else if (reader.last() == '\"') { + return new JsonString(StringConverter.deserialize(reader)); + } else { + return new JsonNumber(NumberConverter.deserializeDouble(reader)); + } + } + + public static void write(JsonWriter writer, JsonValue value) { + if (value == null || value == JsonNull.INSTANCE) writer.writeNull(); + if (value == JsonBoolean.TRUE) writer.writeAscii("true"); + else if (value == JsonBoolean.FALSE) writer.writeAscii("false"); + else if (value instanceof JsonObject) { + JsonObject o = (JsonObject) value; + writer.writeAscii("{"); + boolean first = true; + for (int i = 0; i < o.value.length; i++) { + if (!first) writer.writeAscii(","); + JsonObject.Entry entry = o.value[i]; + writer.writeString(entry.name); + writer.writeAscii(":"); + write(writer, entry.value); + first = false; + } + writer.writeAscii("}"); + } else if (value instanceof JsonArray) { + JsonArray a = (JsonArray) value; + writer.writeAscii("["); + boolean first = true; + for (int i = 0; i