Merge pull request #360 from square/eric.20171004.delegate-adapters

Allow delegates for intermediates in adapters.
This commit is contained in:
Jesse Wilson
2017-10-04 21:53:12 -04:00
committed by GitHub
2 changed files with 44 additions and 5 deletions

View File

@@ -165,7 +165,8 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
} else if (parameterTypes.length == 1 && returnType != void.class) { } else if (parameterTypes.length == 1 && returnType != void.class) {
// List<Integer> pointToJson(Point point) { // List<Integer> pointToJson(Point point) {
final Set<? extends Annotation> returnTypeAnnotations = jsonAnnotations(method); final Set<? extends Annotation> returnTypeAnnotations = jsonAnnotations(method);
Set<? extends Annotation> qualifierAnnotations = jsonAnnotations(parameterAnnotations[0]); final Set<? extends Annotation> qualifierAnnotations =
jsonAnnotations(parameterAnnotations[0]);
boolean nullable = Util.hasNullable(parameterAnnotations[0]); boolean nullable = Util.hasNullable(parameterAnnotations[0]);
return new AdapterMethod(parameterTypes[0], qualifierAnnotations, adapter, method, return new AdapterMethod(parameterTypes[0], qualifierAnnotations, adapter, method,
parameterTypes.length, 1, nullable) { parameterTypes.length, 1, nullable) {
@@ -173,7 +174,10 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
@Override public void bind(Moshi moshi, JsonAdapter.Factory factory) { @Override public void bind(Moshi moshi, JsonAdapter.Factory factory) {
super.bind(moshi, 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) @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) { static AdapterMethod fromAdapter(Object adapter, Method method) {
method.setAccessible(true); method.setAccessible(true);
final Type returnType = method.getGenericReturnType(); final Type returnType = method.getGenericReturnType();
Set<? extends Annotation> returnTypeAnnotations = jsonAnnotations(method); final Set<? extends Annotation> returnTypeAnnotations = jsonAnnotations(method);
final Type[] parameterTypes = method.getGenericParameterTypes(); final Type[] parameterTypes = method.getGenericParameterTypes();
Annotation[][] parameterAnnotations = method.getParameterAnnotations(); Annotation[][] parameterAnnotations = method.getParameterAnnotations();
@@ -240,7 +244,10 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
@Override public void bind(Moshi moshi, JsonAdapter.Factory factory) { @Override public void bind(Moshi moshi, JsonAdapter.Factory factory) {
super.bind(moshi, 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) @Override public Object fromJson(Moshi moshi, JsonReader reader)
@@ -265,7 +272,7 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
List<AdapterMethod> adapterMethods, Type type, Set<? extends Annotation> annotations) { List<AdapterMethod> adapterMethods, Type type, Set<? extends Annotation> annotations) {
for (int i = 0, size = adapterMethods.size(); i < size; i++) { for (int i = 0, size = adapterMethods.size(); i < size; i++) {
AdapterMethod adapterMethod = adapterMethods.get(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; return adapterMethod;
} }
} }

View File

@@ -15,6 +15,8 @@
*/ */
package com.squareup.moshi; package com.squareup.moshi;
import com.squareup.moshi.MoshiTest.Uppercase;
import com.squareup.moshi.MoshiTest.UppercaseAdapterFactory;
import java.io.IOException; import java.io.IOException;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
@@ -136,6 +138,36 @@ public final class AdapterMethodsTest {
assertThat(adapter.fromJson("[\"(5 8)\"]")).isEqualTo(point); assertThat(adapter.fromJson("[\"(5 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<String> 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<String> 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 { @Test public void toJsonOnly() throws Exception {
Moshi moshi = new Moshi.Builder() Moshi moshi = new Moshi.Builder()
.add(new PointAsListOfIntegersToAdapter()) .add(new PointAsListOfIntegersToAdapter())