使用argonaut/circe解码json数组中的单个对象字段
假设我有这样的想法使用argonaut/circe解码json数组中的单个对象字段,json,argonaut,Json,Argonaut,假设我有这样的想法 { "sha": "some sha", "parents": [{ "url": "some url", "sha": "some parent sha" }] } 还有这样的案例课 case class Commit(sha: String, parentShas: List[String]) 在播放json时,我可以这样写: val commitReads: Reads[Commit] = ( (JsPath \ "sha").rea
{
"sha": "some sha",
"parents": [{
"url": "some url",
"sha": "some parent sha"
}]
}
还有这样的案例课
case class Commit(sha: String, parentShas: List[String])
在播放json时,我可以这样写:
val commitReads: Reads[Commit] = (
(JsPath \ "sha").read[String] and
(JsPath \ "parents" \\ "sha").read[List[String]]
)(Commit.apply _)
我正在寻找一种仅解码argonaut/circe中“parent”的“sha”的等效方法,但我没有找到任何方法。“HCursor/ACursor”有下行数组,但从那以后我不知道该怎么办。提前非常感谢 circe和Argonaut都不跟踪在JSON对象中读取了哪些字段,因此您可以忽略额外的
“url”
字段(就像在游戏中一样)。更棘手的部分是找到与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)
}
然后:
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))))
但这并不是一个真正的答案,因为我不会要求你改变你的模型实际答案就没那么有趣了:
case class Commit(sha: String, parentShas: List[String])
object Commit {
val extractSha: Decoder[String] = Decoder.instance(_.get[String]("sha"))
implicit val decodeCommit: Decoder[Commit] = for {
sha <- extractSha
parents <- Decoder.instance(c =>
c.get("parents")(Decoder.decodeCanBuildFrom[String, List](extractSha, implicitly))
)
} yield Commit(sha, parents)
}
case类提交(sha:String,parentShas:List[String])
对象提交{
val-extractSha:Decoder[String]=Decoder.instance(u.get[String](“sha”))
隐式val decodeCommit:Decoder[Commit]=for{
沙
case class Commit(sha: String, parentShas: List[String])
object Commit {
val extractSha: Decoder[String] = Decoder.instance(_.get[String]("sha"))
implicit val decodeCommit: Decoder[Commit] = for {
sha <- extractSha
parents <- Decoder.instance(c =>
c.get("parents")(Decoder.decodeCanBuildFrom[String, List](extractSha, implicitly))
)
} yield Commit(sha, parents)
}