Пользовательская json-сериализация структурных классов

У меня есть некоторый рабочий код модуля Джексона Скала для циклических занятий по классам Скала. Джексон отлично работал для классов с плоскими падежами, но когда я создал класс, содержащий список других классов, то объем кода, который мне, казалось, был нужен, был большим. Рассматривать:

abstract class Message
case class CardDrawn(player: Long, card: Int, mType: String = "CardDrawn") extends Message
case class CardSet(cards: List[CardDrawn], mType: String = "CardSet") extends Message

Чтобы получить CardSet для передачи туда и обратно в json с модулем scala Джексона, я использовал собственный сериализатор / десериализатор, написанный на java:

object ScrumGameMashaller {

  val mapper = new ObjectMapper() 
  val module = new SimpleModule("CustomSerializer")
  module.addSerializer(classOf[CardSet], new CardSetSerializer)
  module.addDeserializer(classOf[CardSet], new CardSetDeserializer)
  val scalaModule = DefaultScalaModule
  mapper.registerModule(scalaModule)
  mapper.registerModule(module)

  def jsonFrom(value: Any): String = {
    import java.io.StringWriter
    val writer = new StringWriter()
    mapper.writeValue(writer, value)
    writer.toString
  }

  private[this] def objectFrom[T: Manifest](value: String): T =
    mapper.readValue(value, typeReference[T])

  private[this] def typeReference[T: Manifest] = new TypeReference[T] {
    override def getType = typeFromManifest(manifest[T])
  }

  private[this] def typeFromManifest(m: Manifest[_]): Type = {
    if (m.typeArguments.isEmpty) { m.runtimeClass }
    else new ParameterizedType {
      def getRawType = m.runtimeClass
      def getActualTypeArguments = m.typeArguments.map(typeFromManifest).toArray
      def getOwnerType = null
    }
  }

с сериализатором:

public class CardSetSerializer extends JsonSerializer {
@Override
    public void serialize(CardSet cardSet, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
        jgen.writeStartObject();
        jgen.writeArrayFieldStart("cards");
        List cardsDrawn = cardSet.cards();
        scala.collection.Iterator iter = cardsDrawn.iterator();
        while(iter.hasNext()){
            CardDrawn cd = iter.next();
            cdSerialize(jgen,cd);
        }
        jgen.writeEndArray();
        jgen.writeStringField("mType", "CardSet");
        jgen.writeEndObject();      
    }

    private void cdSerialize(JsonGenerator jgen, CardDrawn cd) throws IOException, JsonProcessingException {
        jgen.writeStartObject();
        jgen.writeNumberField("player", cd.player());
        jgen.writeNumberField("card", cd.card());
        jgen.writeEndObject();
    }
}

и соответствующий десериализатор:

public class CardSetDeserializer extends JsonDeserializer {

    private static class CardDrawnTuple {
        Long player;
        Integer card;
    }

    @Override
    public CardSet deserialize(JsonParser jsonParser, DeserializationContext cxt) throws IOException, JsonProcessingException {
        ObjectCodec oc = jsonParser.getCodec();
        JsonNode root = oc.readTree(jsonParser);
        JsonNode cards = root.get("cards");
        Iterator i = cards.elements();
        List cardObjects = new ArrayList();
        while( i.hasNext() ){
            CardDrawnTuple t = new CardDrawnTuple();
            ObjectNode c = (ObjectNode) i.next();
            Iterator fields = c.fields();
            while( fields.hasNext() ){
                Entry f = fields.next();
                if( f.getKey().equals("player")) {
                    t.player = f.getValue().asLong();
                } else if( f.getKey().equals("card")){
                    t.card = f.getValue().asInt();
                } else { 
                    System.err.println(CardSetDeserializer.class.getCanonicalName()+ " : unknown field " + f.getKey());
                }
            }
            CardDrawn cd = new CardDrawn(t.player, t.card, "CardDrawn");
            cardObjects.add(cd);
        }

        return new CardSet(JavaConversions.asScalaBuffer(cardObjects).toList(), "CardSet");
    }

}

Это похоже на большой код, чтобы иметь дело с чем-то довольно ванильным в Scala. Можно ли улучшить этот код (что я упустил из-за того, что Джексон должен сделать это легко)? Иначе есть ли библиотека, которая будет автоматически выполнять структурированные кейсы? Примеры Джерксона выглядели легко, но, похоже, от них отказались.

Ответы на вопрос(2)

Ваш ответ на вопрос