From de336ef86ec6af9906d6b4d5a61bfa5a221f2249 Mon Sep 17 00:00:00 2001 From: Eric Cochran Date: Wed, 4 Oct 2017 15:48:02 -0700 Subject: [PATCH] Allow delegates for intermediates in adapters. --- .../squareup/moshi/AdapterMethodsFactory.java | 17 +++++++--- .../squareup/moshi/AdapterMethodsTest.java | 32 +++++++++++++++++++ 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/moshi/src/main/java/com/squareup/moshi/AdapterMethodsFactory.java b/moshi/src/main/java/com/squareup/moshi/AdapterMethodsFactory.java index e9fdf7d..1c90f6c 100644 --- a/moshi/src/main/java/com/squareup/moshi/AdapterMethodsFactory.java +++ b/moshi/src/main/java/com/squareup/moshi/AdapterMethodsFactory.java @@ -165,7 +165,8 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory { } else if (parameterTypes.length == 1 && returnType != void.class) { // List pointToJson(Point point) { final Set returnTypeAnnotations = jsonAnnotations(method); - Set qualifierAnnotations = jsonAnnotations(parameterAnnotations[0]); + final Set qualifierAnnotations = + jsonAnnotations(parameterAnnotations[0]); boolean nullable = Util.hasNullable(parameterAnnotations[0]); return new AdapterMethod(parameterTypes[0], qualifierAnnotations, adapter, method, parameterTypes.length, 1, nullable) { @@ -173,7 +174,10 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory { @Override public void bind(Moshi moshi, JsonAdapter.Factory factory) { super.bind(moshi, factory); - delegate = moshi.adapter(returnType, returnTypeAnnotations); + delegate = Types.equals(parameterTypes[0], returnType) + && qualifierAnnotations.equals(returnTypeAnnotations) + ? moshi.nextAdapter(factory, returnType, returnTypeAnnotations) + : moshi.adapter(returnType, returnTypeAnnotations); } @Override public void toJson(Moshi moshi, JsonWriter writer, @Nullable Object value) @@ -211,7 +215,7 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory { static AdapterMethod fromAdapter(Object adapter, Method method) { method.setAccessible(true); final Type returnType = method.getGenericReturnType(); - Set returnTypeAnnotations = jsonAnnotations(method); + final Set returnTypeAnnotations = jsonAnnotations(method); final Type[] parameterTypes = method.getGenericParameterTypes(); Annotation[][] parameterAnnotations = method.getParameterAnnotations(); @@ -240,7 +244,10 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory { @Override public void bind(Moshi moshi, JsonAdapter.Factory factory) { super.bind(moshi, factory); - delegate = moshi.adapter(parameterTypes[0], qualifierAnnotations); + delegate = Types.equals(parameterTypes[0], returnType) + && qualifierAnnotations.equals(returnTypeAnnotations) + ? moshi.nextAdapter(factory, parameterTypes[0], qualifierAnnotations) + : moshi.adapter(parameterTypes[0], qualifierAnnotations); } @Override public Object fromJson(Moshi moshi, JsonReader reader) @@ -265,7 +272,7 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory { List adapterMethods, Type type, Set annotations) { for (int i = 0, size = adapterMethods.size(); i < size; i++) { AdapterMethod adapterMethod = adapterMethods.get(i); - if (adapterMethod.type.equals(type) && adapterMethod.annotations.equals(annotations)) { + if (Types.equals(adapterMethod.type, type) && adapterMethod.annotations.equals(annotations)) { return adapterMethod; } } diff --git a/moshi/src/test/java/com/squareup/moshi/AdapterMethodsTest.java b/moshi/src/test/java/com/squareup/moshi/AdapterMethodsTest.java index 3da17d3..4060eb6 100644 --- a/moshi/src/test/java/com/squareup/moshi/AdapterMethodsTest.java +++ b/moshi/src/test/java/com/squareup/moshi/AdapterMethodsTest.java @@ -15,6 +15,8 @@ */ package com.squareup.moshi; +import com.squareup.moshi.MoshiTest.Uppercase; +import com.squareup.moshi.MoshiTest.UppercaseAdapterFactory; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -130,6 +132,36 @@ public final class AdapterMethodsTest { assertThat(adapter.fromJson("[{\"x\":5,\"y\":8}]")).isEqualTo(point); } + @Test public void toAndFromWithIntermediate() throws Exception { + Moshi moshi = new Moshi.Builder().add(new Object() { + @FromJson String fromJson(String string) { + return string.substring(1, string.length() - 1); + } + + @ToJson String toJson(String value) { + return "|" + value + "|"; + } + }).build(); + JsonAdapter adapter = moshi.adapter(String.class); + assertThat(adapter.toJson("pizza")).isEqualTo("\"|pizza|\""); + assertThat(adapter.fromJson("\"|pizza|\"")).isEqualTo("pizza"); + } + + @Test public void toAndFromWithIntermediateWithQualifier() throws Exception { + Moshi moshi = new Moshi.Builder().add(new Object() { + @FromJson @Uppercase String fromJson(@Uppercase String string) { + return string.substring(1, string.length() - 1); + } + + @ToJson @Uppercase String toJson(@Uppercase String value) { + return "|" + value + "|"; + } + }).add(new UppercaseAdapterFactory()).build(); + JsonAdapter adapter = moshi.adapter(String.class, Uppercase.class); + assertThat(adapter.toJson("pizza")).isEqualTo("\"|PIZZA|\""); + assertThat(adapter.fromJson("\"|pizza|\"")).isEqualTo("PIZZA"); + } + @Test public void toJsonOnly() throws Exception { Moshi moshi = new Moshi.Builder() .add(new PointAsListOfIntegersToAdapter())