From 5de5d44c5a9581ed3f28d3370d81e52252d33a87 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 14 Jan 2025 23:09:14 +1300 Subject: [PATCH] [core] Add type() method to SimpleMapper that takes a function that creates JsonAdapter Typically, the function is the constructor of the JsonAdapter. This makes it slightly cleaner to create the SimpleMapper.Type, for example: SimpleMapper mapper = SimpleMapper.builder().build(); SimpleMapper.Type myType = mapper.type(MyAdapter::new); --- .../java/io/avaje/json/simple/DSimpleMapper.java | 6 ++++++ .../java/io/avaje/json/simple/SimpleMapper.java | 13 +++++++++++++ .../io/avaje/json/simple/CustomAdapterTest.java | 6 ++++-- .../java/io/avaje/json/node/JsonNodeMapper.java | 13 +++++++++++++ .../io/avaje/json/node/adapter/DJsonNodeMapper.java | 6 ++++++ .../java/io/avaje/json/node/CustomAdapterTest.java | 4 +--- 6 files changed, 43 insertions(+), 5 deletions(-) diff --git a/json-core/src/main/java/io/avaje/json/simple/DSimpleMapper.java b/json-core/src/main/java/io/avaje/json/simple/DSimpleMapper.java index 24f35949..fb11eedc 100644 --- a/json-core/src/main/java/io/avaje/json/simple/DSimpleMapper.java +++ b/json-core/src/main/java/io/avaje/json/simple/DSimpleMapper.java @@ -9,6 +9,7 @@ import java.util.List; import java.util.Map; +import java.util.function.Function; final class DSimpleMapper implements SimpleMapper { @@ -34,6 +35,11 @@ public Type type(JsonAdapter myAdapter) { return new DTypeMapper<>(myAdapter, jsonStream); } + @Override + public Type type(Function> adapterFunction) { + return type(adapterFunction.apply(this)); + } + @Override public Type object() { return objectType; 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 d3a3629f..9566a937 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 @@ -12,6 +12,7 @@ import java.io.Writer; import java.util.List; import java.util.Map; +import java.util.function.Function; /** * A mapper for mapping to basic Java types. @@ -136,6 +137,18 @@ static Builder builder() { */ Type type(JsonAdapter customAdapter); + /** + * Return a Type specific mapper using a function that creates a JsonAdapter. + *

+ * Often the adapterFunction is the constructor of the custom JsonAdapter where + * the constructor takes SimpleMapper as the only argument. + * + * @param adapterFunction The function that creates a JsonAdapter. + * @param The type of the class to map to/from json. + * @return The Type specific mapper. + */ + Type type(Function> adapterFunction); + default JsonExtract extract(Map map) { return new DExtract(map); } diff --git a/json-core/src/test/java/io/avaje/json/simple/CustomAdapterTest.java b/json-core/src/test/java/io/avaje/json/simple/CustomAdapterTest.java index db92ecfd..f7d4ecc1 100644 --- a/json-core/src/test/java/io/avaje/json/simple/CustomAdapterTest.java +++ b/json-core/src/test/java/io/avaje/json/simple/CustomAdapterTest.java @@ -21,13 +21,15 @@ class CustomAdapterTest { @Test void mapUsingCustomAdapter() { + SimpleMapper mapper = SimpleMapper.builder().build(); + SimpleMapper.Type myType = mapper.type(MyAdapter::new); MyCustomType source = new MyCustomType(); source.foo = "hi"; source.bar = 42; - String asJson = type.toJson(source); + String asJson = myType.toJson(source); - MyCustomType fromJson = type.fromJson(asJson); + MyCustomType fromJson = myType.fromJson(asJson); assertThat(fromJson.foo).isEqualTo(source.foo); assertThat(fromJson.bar).isEqualTo(source.bar); 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 508b55e8..7c57a6a1 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 @@ -13,6 +13,7 @@ import java.io.Reader; import java.io.Writer; import java.lang.reflect.Type; +import java.util.function.Function; /** * Provide JsonAdapters for the JsonNode types. @@ -204,6 +205,18 @@ static Builder builder() { */ SimpleMapper.Type type(JsonAdapter customAdapter); + /** + * Return a Type specific mapper using a function that creates a JsonAdapter. + *

+ * Often the adapterFunction is the constructor of the custom JsonAdapter where + * the constructor takes JsonNodeMapper as the only argument. + * + * @param adapterFunction The function that creates a JsonAdapter. + * @param The type of the class to map to/from json. + * @return The Type specific mapper. + */ + SimpleMapper.Type type(Function> adapterFunction); + /** * Build the JsonNodeMapper. */ 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 9a2281a1..2d81ec13 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 @@ -9,6 +9,7 @@ import io.avaje.json.stream.JsonStream; import java.lang.reflect.Type; +import java.util.function.Function; final class DJsonNodeMapper implements JsonNodeMapper { @@ -42,6 +43,11 @@ public SimpleMapper.Type type(JsonAdapter customAdapter) { return new DMapper<>(customAdapter, jsonStream); } + @Override + public SimpleMapper.Type type(Function> adapterFunction) { + return type(adapterFunction.apply(this)); + } + @Override public SimpleMapper.Type nodeMapper() { return new DMapper<>(nodeAdapter, 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 2462db36..781aa210 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 @@ -21,9 +21,7 @@ class CustomAdapterTest { @Test void propertyNames() { - - var adapter = new MyAdapter2(mapper); - SimpleMapper.Type type = mapper.type(adapter); + SimpleMapper.Type type = mapper.type(MyAdapter2::new); var source = as("a", 1); String asJson = type.toJson(source);