Allow easy delegates in adapter methods. (#272)

This commit is contained in:
Eric Cochran
2017-03-27 18:48:19 -07:00
committed by Jesse Wilson
parent 1b634bbb74
commit 718f832864
2 changed files with 64 additions and 12 deletions

View File

@@ -55,8 +55,8 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
delegate = null; delegate = null;
} }
if (toAdapter != null) toAdapter.bind(moshi); if (toAdapter != null) toAdapter.bind(moshi, this);
if (fromAdapter != null) fromAdapter.bind(moshi); if (fromAdapter != null) fromAdapter.bind(moshi, this);
return new JsonAdapter<Object>() { return new JsonAdapter<Object>() {
@Override public void toJson(JsonWriter writer, Object value) throws IOException { @Override public void toJson(JsonWriter writer, Object value) throws IOException {
@@ -170,8 +170,8 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
parameterTypes.length, 1, nullable) { parameterTypes.length, 1, nullable) {
private JsonAdapter<Object> delegate; private JsonAdapter<Object> delegate;
@Override public void bind(Moshi moshi) { @Override public void bind(Moshi moshi, JsonAdapter.Factory factory) {
super.bind(moshi); super.bind(moshi, factory);
delegate = moshi.adapter(returnType, returnTypeAnnotations); delegate = moshi.adapter(returnType, returnTypeAnnotations);
} }
@@ -235,8 +235,8 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
parameterTypes.length, 1, nullable) { parameterTypes.length, 1, nullable) {
JsonAdapter<Object> delegate; JsonAdapter<Object> delegate;
@Override public void bind(Moshi moshi) { @Override public void bind(Moshi moshi, JsonAdapter.Factory factory) {
super.bind(moshi); super.bind(moshi, factory);
delegate = moshi.adapter(parameterTypes[0], qualifierAnnotations); delegate = moshi.adapter(parameterTypes[0], qualifierAnnotations);
} }
@@ -289,14 +289,17 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
this.nullable = nullable; this.nullable = nullable;
} }
public void bind(Moshi moshi) { public void bind(Moshi moshi, JsonAdapter.Factory factory) {
if (jsonAdapters.length > 0) { if (jsonAdapters.length > 0) {
Type[] parameterTypes = method.getGenericParameterTypes(); Type[] parameterTypes = method.getGenericParameterTypes();
Annotation[][] parameterAnnotations = method.getParameterAnnotations(); Annotation[][] parameterAnnotations = method.getParameterAnnotations();
for (int i = adaptersOffset, size = parameterTypes.length; i < size; i++) { for (int i = adaptersOffset, size = parameterTypes.length; i < size; i++) {
jsonAdapters[i - adaptersOffset] = moshi.adapter( Type type = ((ParameterizedType) parameterTypes[i]).getActualTypeArguments()[0];
((ParameterizedType) parameterTypes[i]).getActualTypeArguments()[0], Set<? extends Annotation> jsonAnnotations = jsonAnnotations(parameterAnnotations[i]);
jsonAnnotations(parameterAnnotations[i])); jsonAdapters[i - adaptersOffset] =
Types.equals(this.type, type) && annotations.equals(jsonAnnotations)
? moshi.nextAdapter(factory, type, jsonAnnotations)
: moshi.adapter(type, jsonAnnotations);
} }
} }
} }

View File

@@ -79,6 +79,55 @@ public final class AdapterMethodsTest {
} }
} }
private static final class PointJsonAdapterWithDelegate {
@FromJson Point fromJson(JsonReader reader, JsonAdapter<Point> delegate) throws IOException {
reader.beginArray();
Point value = delegate.fromJson(reader);
reader.endArray();
return value;
}
@ToJson void toJson(JsonWriter writer, Point value, JsonAdapter<Point> delegate)
throws IOException {
writer.beginArray();
delegate.toJson(writer, value);
writer.endArray();
}
}
private static final class PointJsonAdapterWithDelegateWithQualifier {
@FromJson @WithParens Point fromJson(JsonReader reader, JsonAdapter<Point> delegate)
throws IOException {
reader.beginArray();
Point value = delegate.fromJson(reader);
reader.endArray();
return value;
}
@ToJson void toJson(JsonWriter writer, @WithParens Point value, JsonAdapter<Point> delegate)
throws IOException {
writer.beginArray();
delegate.toJson(writer, value);
writer.endArray();
}
}
@Test public void toAndFromWithDelegate() throws Exception {
Moshi moshi = new Moshi.Builder().add(new PointJsonAdapterWithDelegate()).build();
JsonAdapter<Point> adapter = moshi.adapter(Point.class);
Point point = new Point(5, 8);
assertThat(adapter.toJson(point)).isEqualTo("[{\"x\":5,\"y\":8}]");
assertThat(adapter.fromJson("[{\"x\":5,\"y\":8}]")).isEqualTo(point);
}
@Test public void toAndFromWithDelegateWithQualifier() throws Exception {
Moshi moshi = new Moshi.Builder().add(new PointJsonAdapterWithDelegateWithQualifier()).build();
JsonAdapter<Point> adapter = moshi.adapter(Point.class, WithParens.class);
Point point = new Point(5, 8);
assertThat(adapter.toJson(point)).isEqualTo("[{\"x\":5,\"y\":8}]");
assertThat(adapter.fromJson("[{\"x\":5,\"y\":8}]")).isEqualTo(point);
}
@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())
@@ -308,7 +357,7 @@ public final class AdapterMethodsTest {
} }
static class NullableIntToJsonAdapter { static class NullableIntToJsonAdapter {
@FromJson int intToJson(JsonReader reader) throws IOException { @FromJson int jsonToInt(JsonReader reader) throws IOException {
if (reader.peek() == JsonReader.Token.NULL) { if (reader.peek() == JsonReader.Token.NULL) {
reader.nextNull(); reader.nextNull();
return -1; return -1;
@@ -316,7 +365,7 @@ public final class AdapterMethodsTest {
return reader.nextInt(); return reader.nextInt();
} }
@ToJson void jsonToInt(JsonWriter writer, int value) throws IOException { @ToJson void intToJson(JsonWriter writer, int value) throws IOException {
if (value == -1) { if (value == -1) {
writer.nullValue(); writer.nullValue();
} else { } else {