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;
}
if (toAdapter != null) toAdapter.bind(moshi);
if (fromAdapter != null) fromAdapter.bind(moshi);
if (toAdapter != null) toAdapter.bind(moshi, this);
if (fromAdapter != null) fromAdapter.bind(moshi, this);
return new JsonAdapter<Object>() {
@Override public void toJson(JsonWriter writer, Object value) throws IOException {
@@ -170,8 +170,8 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
parameterTypes.length, 1, nullable) {
private JsonAdapter<Object> delegate;
@Override public void bind(Moshi moshi) {
super.bind(moshi);
@Override public void bind(Moshi moshi, JsonAdapter.Factory factory) {
super.bind(moshi, factory);
delegate = moshi.adapter(returnType, returnTypeAnnotations);
}
@@ -235,8 +235,8 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
parameterTypes.length, 1, nullable) {
JsonAdapter<Object> delegate;
@Override public void bind(Moshi moshi) {
super.bind(moshi);
@Override public void bind(Moshi moshi, JsonAdapter.Factory factory) {
super.bind(moshi, factory);
delegate = moshi.adapter(parameterTypes[0], qualifierAnnotations);
}
@@ -289,14 +289,17 @@ final class AdapterMethodsFactory implements JsonAdapter.Factory {
this.nullable = nullable;
}
public void bind(Moshi moshi) {
public void bind(Moshi moshi, JsonAdapter.Factory factory) {
if (jsonAdapters.length > 0) {
Type[] parameterTypes = method.getGenericParameterTypes();
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
for (int i = adaptersOffset, size = parameterTypes.length; i < size; i++) {
jsonAdapters[i - adaptersOffset] = moshi.adapter(
((ParameterizedType) parameterTypes[i]).getActualTypeArguments()[0],
jsonAnnotations(parameterAnnotations[i]));
Type type = ((ParameterizedType) parameterTypes[i]).getActualTypeArguments()[0];
Set<? extends Annotation> jsonAnnotations = 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 {
Moshi moshi = new Moshi.Builder()
.add(new PointAsListOfIntegersToAdapter())
@@ -308,7 +357,7 @@ public final class AdapterMethodsTest {
}
static class NullableIntToJsonAdapter {
@FromJson int intToJson(JsonReader reader) throws IOException {
@FromJson int jsonToInt(JsonReader reader) throws IOException {
if (reader.peek() == JsonReader.Token.NULL) {
reader.nextNull();
return -1;
@@ -316,7 +365,7 @@ public final class AdapterMethodsTest {
return reader.nextInt();
}
@ToJson void jsonToInt(JsonWriter writer, int value) throws IOException {
@ToJson void intToJson(JsonWriter writer, int value) throws IOException {
if (value == -1) {
writer.nullValue();
} else {