diff --git a/examples/src/main/java/com/squareup/moshi/recipes/MultipleFormats.java b/examples/src/main/java/com/squareup/moshi/recipes/MultipleFormats.java new file mode 100644 index 0000000..9162620 --- /dev/null +++ b/examples/src/main/java/com/squareup/moshi/recipes/MultipleFormats.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2018 Square, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.squareup.moshi.recipes; + +import com.squareup.moshi.FromJson; +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.JsonDataException; +import com.squareup.moshi.JsonQualifier; +import com.squareup.moshi.JsonReader; +import com.squareup.moshi.JsonWriter; +import com.squareup.moshi.Moshi; +import com.squareup.moshi.ToJson; +import com.squareup.moshi.recipes.models.Card; +import com.squareup.moshi.recipes.models.Suit; +import java.io.IOException; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +public final class MultipleFormats { + public void run() throws Exception { + Moshi moshi = new Moshi.Builder() + .add(new MultipleFormatsCardAdapter()) + .add(new CardStringAdapter()) + .build(); + + JsonAdapter cardAdapter = moshi.adapter(Card.class); + + // Decode cards from one format or the other. + System.out.println(cardAdapter.fromJson("\"5D\"")); + System.out.println(cardAdapter.fromJson("{\"suit\": \"SPADES\", \"rank\": 5}")); + + // Cards are always encoded as strings. + System.out.println(cardAdapter.toJson(new Card('5', Suit.CLUBS))); + } + + /** Handles cards either as strings "5D" or as objects {"suit": "SPADES", "rank": 5}. */ + public final class MultipleFormatsCardAdapter { + @ToJson void toJson(JsonWriter writer, Card value, + @CardString JsonAdapter stringAdapter) throws IOException { + stringAdapter.toJson(writer, value); + } + + @FromJson Card fromJson(JsonReader reader, @CardString JsonAdapter stringAdapter, + JsonAdapter defaultAdapter) throws IOException { + if (reader.peek() == JsonReader.Token.STRING) { + return stringAdapter.fromJson(reader); + } else { + return defaultAdapter.fromJson(reader); + } + } + } + + /** Handles cards as strings only. */ + public final class CardStringAdapter { + @ToJson String toJson(@CardString Card card) { + return card.rank + card.suit.name().substring(0, 1); + } + + @FromJson @CardString Card fromJson(String card) { + if (card.length() != 2) throw new JsonDataException("Unknown card: " + card); + + char rank = card.charAt(0); + switch (card.charAt(1)) { + case 'C': return new Card(rank, Suit.CLUBS); + case 'D': return new Card(rank, Suit.DIAMONDS); + case 'H': return new Card(rank, Suit.HEARTS); + case 'S': return new Card(rank, Suit.SPADES); + default: throw new JsonDataException("unknown suit: " + card); + } + } + } + + @Retention(RetentionPolicy.RUNTIME) + @JsonQualifier + @interface CardString { + } + + public static void main(String[] args) throws Exception { + new MultipleFormats().run(); + } +}