diff --git a/json-core/src/main/java/io/avaje/json/simple/SimpleMapper.java b/json-core/src/main/java/io/avaje/json/simple/SimpleMapper.java index 34cc0ba9..fd0d22ab 100644 --- a/json-core/src/main/java/io/avaje/json/simple/SimpleMapper.java +++ b/json-core/src/main/java/io/avaje/json/simple/SimpleMapper.java @@ -52,7 +52,16 @@ static Builder builder() { PropertyNames properties(String... names); /** - * Return a mapper for Object with more reading/writing options. + * Return a Type specific mapper for the given JsonAdapter. + * + * @param customAdapter The custom adapter to use. + * @param The type of the class to map to/from json. + * @return The Type specific mapper. + */ + Type type(JsonAdapter customAdapter); + + /** + * Return a mapper for any json content. */ Type object(); @@ -66,15 +75,6 @@ static Builder builder() { */ Type> list(); - /** - * Return a Type specific mapper for the given JsonAdapter. - * - * @param customAdapter The custom adapter to use. - * @param The type of the class to map to/from json. - * @return The Type specific mapper. - */ - Type type(JsonAdapter customAdapter); - /** * Write the object to JSON string. *

diff --git a/json-node/src/main/java/io/avaje/json/node/JsonNodeMapper.java b/json-node/src/main/java/io/avaje/json/node/JsonNodeMapper.java index 66ccf1c5..a9f1844f 100644 --- a/json-node/src/main/java/io/avaje/json/node/JsonNodeMapper.java +++ b/json-node/src/main/java/io/avaje/json/node/JsonNodeMapper.java @@ -1,6 +1,7 @@ package io.avaje.json.node; import io.avaje.json.JsonAdapter; +import io.avaje.json.PropertyNames; import io.avaje.json.node.adapter.NodeAdapterBuilder; import io.avaje.json.simple.SimpleMapper; import io.avaje.json.stream.JsonStream; @@ -19,8 +20,8 @@ * static final JsonNodeMapper mapper = JsonNodeMapper.builder().build(); * * JsonArray jsonArray = JsonArray.create() - * .add(JsonInteger.of(42)) - * .add(JsonString.of("foo")); + * .add(42) + * .add("foo"); * * var asJson = mapper.toJson(jsonArray); * @@ -42,13 +43,21 @@ static Builder builder() { } /** - * Create a NodeMapper for the specific type given the JsonAdapter. + * Return the property names as PropertyNames. + *

+ * Provides the option of optimising the writing of json for property names + * by having them already escaped and encoded rather than as plain strings. + */ + PropertyNames properties(String... names); + + /** + * Return a Type specific mapper for the given JsonAdapter. * - * @param customAdapter The type specific JsonAdapter to use. - * @param The specific custom type being mapped. - * @return The type specific NodeMapper. + * @param customAdapter The custom adapter to use. + * @param The type of the class to map to/from json. + * @return The Type specific mapper. */ - SimpleMapper.Type mapper(JsonAdapter customAdapter); + SimpleMapper.Type type(JsonAdapter customAdapter); /** * Return a NodeMapper for ANY json content. diff --git a/json-node/src/main/java/io/avaje/json/node/adapter/DJsonNodeMapper.java b/json-node/src/main/java/io/avaje/json/node/adapter/DJsonNodeMapper.java index ead34bb8..6152f80c 100644 --- a/json-node/src/main/java/io/avaje/json/node/adapter/DJsonNodeMapper.java +++ b/json-node/src/main/java/io/avaje/json/node/adapter/DJsonNodeMapper.java @@ -2,6 +2,7 @@ import io.avaje.json.JsonAdapter; import io.avaje.json.JsonReader; +import io.avaje.json.PropertyNames; import io.avaje.json.node.*; import io.avaje.json.simple.SimpleMapper; import io.avaje.json.stream.JsonStream; @@ -31,7 +32,12 @@ final class DJsonNodeMapper implements JsonNodeMapper { } @Override - public SimpleMapper.Type mapper(JsonAdapter customAdapter) { + public PropertyNames properties(String... names) { + return jsonStream.properties(names); + } + + @Override + public SimpleMapper.Type type(JsonAdapter customAdapter) { return new DMapper<>(customAdapter, jsonStream); } diff --git a/json-node/src/test/java/io/avaje/json/node/CustomAdapterTest.java b/json-node/src/test/java/io/avaje/json/node/CustomAdapterTest.java index d0bf5d6d..2462db36 100644 --- a/json-node/src/test/java/io/avaje/json/node/CustomAdapterTest.java +++ b/json-node/src/test/java/io/avaje/json/node/CustomAdapterTest.java @@ -3,6 +3,7 @@ import io.avaje.json.JsonAdapter; import io.avaje.json.JsonReader; import io.avaje.json.JsonWriter; +import io.avaje.json.PropertyNames; import io.avaje.json.simple.SimpleMapper; import org.junit.jupiter.api.Test; @@ -16,7 +17,21 @@ class CustomAdapterTest { static final JsonNodeMapper mapper = JsonNodeMapper.builder().build(); static final MyAdapter myAdapter = new MyAdapter(mapper); - static final SimpleMapper.Type typeMapper = mapper.mapper(myAdapter); + static final SimpleMapper.Type typeMapper = mapper.type(myAdapter); + + @Test + void propertyNames() { + + var adapter = new MyAdapter2(mapper); + SimpleMapper.Type type = mapper.type(adapter); + + var source = as("a", 1); + String asJson = type.toJson(source); + assertThat(asJson).isEqualTo("{\"foo\":\"a\",\"bar\":1}"); + + MyCustomType myCustomType = type.fromJson(asJson); + assertThat(myCustomType).isEqualTo(source); + } @Test void mapUsingCustomAdapter() { @@ -110,4 +125,48 @@ public MyCustomType fromJson(JsonReader reader) { return myCustomType; } } + + static class MyAdapter2 implements JsonAdapter { + + final SimpleMapper.Type objectMapper; + final PropertyNames names; + + public MyAdapter2(JsonNodeMapper mapper) { + this.objectMapper = mapper.objectMapper(); + this.names = mapper.properties("foo", "bar"); + } + + @Override + public void toJson(JsonWriter writer, MyCustomType value) { + writer.beginObject(names); + writer.name(0); + writer.value(value.foo); + writer.name(1); + writer.value(value.bar); + writer.endObject(); + } + + @Override + public MyCustomType fromJson(JsonReader reader) { + MyCustomType myCustomType = new MyCustomType(); + reader.beginObject(names); + + String name; + while (reader.hasNextField()) { + name = reader.nextField(); + switch (name) { + case "foo": + myCustomType.foo = reader.readString(); + break; + case "bar": + myCustomType.bar = reader.readInt(); + break; + default: + reader.unmappedField(name); + reader.skipValue(); + } + } + return myCustomType; + } + } }