Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve CardAdapter Handling and Validations #1909

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Map;

public final class MultipleFormats {
public void run() throws Exception {
Moshi moshi =
new Moshi.Builder()
.add(new MultipleFormatsCardAdapter())
.add(new CardStringAdapter())
.build();
Moshi moshi = new Moshi.Builder()
.add(new MultipleFormatsCardAdapter())
.add(new CardStringAdapter())
.build();

JsonAdapter<Card> cardAdapter = moshi.adapter(Card.class);

Expand All @@ -47,59 +47,69 @@ public void run() throws Exception {
System.out.println(cardAdapter.toJson(new Card('5', Suit.CLUBS)));
}

/** Handles cards either as strings "5D" or as objects {"suit": "SPADES", "rank": 5}. */
/**
* 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<Card> stringAdapter)
throws IOException {
if (value == null || value.suit == null || value.rank == 0) {
throw new JsonDataException("Invalid card: " + value);
}
stringAdapter.toJson(writer, value);
}

@FromJson
Card fromJson(
JsonReader reader,
@CardString JsonAdapter<Card> stringAdapter,
JsonAdapter<Card> defaultAdapter)
throws IOException {
JsonAdapter<Card> defaultAdapter) throws IOException {
if (reader.peek() == JsonReader.Token.STRING) {
return stringAdapter.fromJson(reader);
} else {
return defaultAdapter.fromJson(reader);
}
return defaultAdapter.fromJson(reader);
}
}

/** Handles cards as strings only. */
public final class CardStringAdapter {
private static final Map<Character, Suit> SUIT_MAP = Map.of(
'C', Suit.CLUBS,
'D', Suit.DIAMONDS,
'H', Suit.HEARTS,
'S', Suit.SPADES);

@ToJson
String toJson(@CardString Card card) {
if (card == null || card.suit == null || card.rank == 0) {
throw new JsonDataException("Invalid 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);
if (card == null || card.length() != 2) {
throw new JsonDataException("Invalid card format: " + 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);
Suit suit = SUIT_MAP.get(card.charAt(1));
if (suit == null) {
throw new JsonDataException("Unknown suit: " + card.charAt(1));
}

return new Card(rank, suit);
}
}

@Retention(RetentionPolicy.RUNTIME)
@JsonQualifier
@interface CardString {}
@interface CardString {
}

public static void main(String[] args) throws Exception {
new MultipleFormats().run();
Expand Down