2016-04-08 7 views
2

と私は、このように読み書くことができるようにJSONに遊び-JSONでデコード単一のフィールドアルゴノート/キルケ

{ 
    "sha": "some sha", 
    "parents": [{ 
    "url": "some url", 
    "sha": "some parent sha" 
    }] 
} 

と、このようなケースクラス

case class Commit(sha: String, parentShas: List[String]) 

を持っていると仮定:私は、アルゴノート/キルケの復号「親」の唯一の「SHA」の同等の方法を探していますが、私はいずれかを発見していない

val commitReads: Reads[Commit] = (
    (JsPath \ "sha").read[String] and 
    (JsPath \ "parents" \\ "sha").read[List[String]] 
)(Commit.apply _) 

。 "HCursor/ACursor"にはdownArrayがありますが、そこから私は何をすべきか分かりません。事前にどうもありがとうございました!

答えて

2

circeもArgonautも、JSONオブジェクトで読み取られたフィールドを追跡しないため、余分な"url"フィールドを無視することができます(Playと同様)。より手の込んだ部分はPlayの\\に相当するものを見つけていますが、私はそれを追加する必要があると確信していますが、今のところcirceは持っていません。

まず第一に、あなたが別のSHAタイプを持っている場合、これは比較的簡単です:

import io.circe.Decoder 

val doc = """ 
{ 
    "sha": "some sha", 
    "parents": [{ 
    "url": "some url", 
    "sha": "some parent sha" 
    }] 
} 
""" 

case class Sha(value: String) 

object Sha { 
    implicit val decodeSha: Decoder[Sha] = Decoder.instance(_.get[String]("sha")).map(Sha(_)) 
} 

case class Commit(sha: Sha, parentShas: List[Sha]) 

object Commit { 
    implicit val decodeCommit: Decoder[Commit] = for { 
    sha <- Decoder[Sha] 
    parents <- Decoder.instance(_.get[List[Sha]]("parents")) 
    } yield Commit(sha, parents) 
} 

それとも、猫の応用的な構文を使用して:

import cats.syntax.cartesian._ 

implicit val decodeCommit: Decoder[Commit] = 
    (Decoder[Sha] |@| Decoder.instance(_.get[List[Sha]]("parents"))).map(Commit(_, _)) 

そして:

scala> import io.circe.jawn._ 
import io.circe.jawn._ 

scala> decode[Commit](doc) 
res0: cats.data.Xor[io.circe.Error,Commit] = Right(Commit(Sha(some sha),List(Sha(some parent sha)))) 

しかし、私はあなたのモデルを変更するように頼むつもりはないので、それは本当の答えではありません。 :)実際の答えはちょっと楽しいです。

これは悪いことですが、それは必要ですが、それは機能します。私はちょうどan issueを提出して、これが将来のcirceリリースで良くなることを確認しました。