Formato Json para tuplas em jogo json

Eu estava em uma situação em que precisava de uma lista de três (talvez menos) valores relacionados (as três medidas de um objeto físico).

Pensei em usar uma lista para armazená-los, mas não gostei dessa solução porque uma lista tem um comprimento arbitrário e, no meu caso, não quero ter mais de três valores.

Outra solução que considerei foi uma aula de caso Dimensions(1:Option[Measure], 2:Option[Measure], 3: Option[Measure])mas achei que seria um exagero e, além disso, não sei de antemão qual é a altura, qual a largura, etc. então tive que usar esses nomes de campos horríveis (1, 2 e 3).

Finalmente, decidi usar uma tupla (Opção [Medida], Opção [Medida], Opção [Medida]) como uma alternativa leve para a classe de caso.

Quando se tratou de serializar o valor, as macros play-json reclamaram que eu não tinha um formatador para (Opção [Medida], Opção [Medida], Opção [Medida]). Depois de pesquisar no Google, encontrei este tópico https://groups.google.com/forum/#!topic/play-framework/kn-gRW8KSwQ, onde é explicado por que não é fornecido por padrão (alerta de spoiler: falta de suporte de JSON para tuplas tem algo a ver com isso :)) e, felizmente para mim, um exemplo de código de como resolver o problema 🙂

implicit def tuple3Reads[A, B, C](implicit aReads: Reads[A], bReads: Reads[B], cReads: Reads[C]):    Reads[Tuple3[A, B, C]] = Reads[Tuple3[A, B, C]] {
case JsArray(arr) if arr.size == 3 => for {
a
<- aReads.reads(arr(0))
b
<- bReads.reads(arr(1))
c
<- cReads.reads(arr(2))
} yield (a, b, c)
case _ => JsError(Seq(JsPath() -> Seq(ValidationError("Expected array of three elements"))))
}

implicit def tuple2Writes[A, B, C](implicit aWrites: Writes[A], bWrites: Writes[B], cWrites: Writes[C]): Writes[Tuple3[A, B, C]] = new Writes[Tuple3[A, B, C]] {
def writes(tuple: Tuple3[A, B, C]) = JsArray(Seq(aWrites.writes(tuple._1), bWrites.writes(tuple._2), cWrites.writes(tuple._3)))

}

Se você não gosta da convenção (mapeie uma tupla para uma matriz JSON), você sempre pode usar combinadores JSON conforme descrito aqui: http://www.playframework.com/documentation/2.1-RC2/ScalaJsonCombinators