removed limitation where subtypes should be unique (#856)

* removed limitation where subtypes should be unique

There can be use cases where different type labels should match with the same subtype

* added test for PolymorphicJsonAdapter non unique subtypes
This commit is contained in:
Nuno Gomes
2019-06-20 16:39:19 +01:00
committed by Zac Sweers
parent 54c44c5570
commit 687acba760
2 changed files with 19 additions and 13 deletions

View File

@@ -154,8 +154,8 @@ public final class PolymorphicJsonAdapterFactory<T> implements JsonAdapter.Facto
public PolymorphicJsonAdapterFactory<T> withSubtype(Class<? extends T> subtype, String label) { public PolymorphicJsonAdapterFactory<T> withSubtype(Class<? extends T> subtype, String label) {
if (subtype == null) throw new NullPointerException("subtype == null"); if (subtype == null) throw new NullPointerException("subtype == null");
if (label == null) throw new NullPointerException("label == null"); if (label == null) throw new NullPointerException("label == null");
if (labels.contains(label) || subtypes.contains(subtype)) { if (labels.contains(label)) {
throw new IllegalArgumentException("Subtypes and labels must be unique."); throw new IllegalArgumentException("Labels must be unique.");
} }
List<String> newLabels = new ArrayList<>(labels); List<String> newLabels = new ArrayList<>(labels);
newLabels.add(label); newLabels.add(label);

View File

@@ -160,16 +160,22 @@ public final class PolymorphicJsonAdapterFactoryTest {
assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT); assertThat(reader.peek()).isEqualTo(JsonReader.Token.END_DOCUMENT);
} }
@Test public void uniqueSubtypes() { @Test public void nonUniqueSubtypes() throws IOException {
PolymorphicJsonAdapterFactory<Message> factory = Moshi moshi = new Moshi.Builder()
PolymorphicJsonAdapterFactory.of(Message.class, "type") .add(PolymorphicJsonAdapterFactory.of(Message.class, "type")
.withSubtype(Success.class, "success"); .withSubtype(Success.class, "success")
try { .withSubtype(Success.class, "data")
factory.withSubtype(Success.class, "data"); .withSubtype(Error.class, "error"))
fail(); .build();
} catch (IllegalArgumentException expected) {
assertThat(expected).hasMessage("Subtypes and labels must be unique."); JsonAdapter<Message> adapter = moshi.adapter(Message.class);
}
assertThat(adapter.fromJson("{\"type\":\"success\",\"value\":\"Okay!\"}"))
.isEqualTo(new Success("Okay!"));
assertThat(adapter.fromJson("{\"type\":\"data\",\"value\":\"Data!\"}"))
.isEqualTo(new Success("Data!"));
assertThat(adapter.fromJson("{\"type\":\"error\",\"error_logs\":{\"order\":66}}"))
.isEqualTo(new Error(Collections.<String, Object>singletonMap("order", 66d)));
} }
@Test public void uniqueLabels() { @Test public void uniqueLabels() {
@@ -180,7 +186,7 @@ public final class PolymorphicJsonAdapterFactoryTest {
factory.withSubtype(Error.class, "data"); factory.withSubtype(Error.class, "data");
fail(); fail();
} catch (IllegalArgumentException expected) { } catch (IllegalArgumentException expected) {
assertThat(expected).hasMessage("Subtypes and labels must be unique."); assertThat(expected).hasMessage("Labels must be unique.");
} }
} }