2017-01-09 88 views
1

无法解码集我想这一块的JSON解码:在瑟茜

{ 
    "id" : "e07cff6a-bbf7-4bc9-b2ec-ff2ea8e46288", 
    "paper" : { 
    "title" : "Example Title", 
    "authors" : [ 
     "1bf5e911-8878-4e06-ba8e-8159aadb052c" 
    ] 
    } 
} 

然而,当它到达了集合的一部分,它的失败。该错误消息没有帮助。

DecodingFailure([A]Set[A], List()) 

这里是我的docoders:

implicit val paperIdDecoder: Decoder[PaperId] = Decoder.decodeString.emap[PaperId] { str ⇒ 
    Either.catchNonFatal(PaperId(str)).leftMap(_.getMessage) 
    } 

    implicit val paperAuthorDecoder: Decoder[PaperAuthor] = Decoder.decodeString.emap[PaperAuthor] { str ⇒ 
    Either.catchNonFatal(PaperAuthor(str)).leftMap(_.getMessage) 
    } 

    implicit val paperDecoder: Decoder[Paper] = { 
    for { 
     title <- Decoder.decodeString 
     authors <- Decoder.decodeSet[PaperAuthor] 
    } yield Paper(title, authors) 
    } 

    implicit val paperViewDecoder: Decoder[PublishedPaperView] = for { 
    id <- Decoder[PaperId] 
    paper <- Decoder[Paper] 
    } yield PublishedPaperView(id, paper) 

这里使用的情况下类:

case class PublishedPaperView(id: PaperId, paper: Paper) 

case class PaperId(value: String) 

case class Paper(title: String, authors: Set[PaperAuthor]) 

case class PaperAuthor(value: String) 

回答

1

虽然错误说明是远远explicative,你的问题是关系到一个错误使用解码器的monadic API:记住理解是一个map/flatMap的语法糖。

io.circe.Decoder

/** 
    * Monadically bind a function over this [[Decoder]]. 
    */ 
    final def flatMap[B](f: A => Decoder[B]): Decoder[B] = new Decoder[B] { 
    final def apply(c: HCursor): Decoder.Result[B] = self(c).flatMap(a => f(a)(c)) 

    override def tryDecode(c: ACursor): Decoder.Result[B] = { 
     self.tryDecode(c).flatMap(a => f(a).tryDecode(c)) 
    } 

    override def decodeAccumulating(c: HCursor): AccumulatingDecoder.Result[B] = 
     self.decodeAccumulating(c).andThen(result => f(result).decodeAccumulating(c)) 
    } 

展望这个代码,你看,当你flatMap解码器,你会得到一个新的解码器在同一光标操作:光标解析操作的当前位置。

在下面的代码:

implicit val paperDecoder: Decoder[Paper] = { 
    for { 
     title <- Decoder.decodeString 
     authors <- Decoder.decodeSet[PaperAuthor] 
    } yield Paper(title, authors) 
    } 

光标在对象的开头都指向当您尝试解码标题和作者。如果您不使用半自动或自动生成,并且您本身使用API​​工作,则需要自己移动光标,如

implicit val paperDecoder: Decoder[Paper] = Decoder.instance(cursor => Xor.right(Paper("",Set.empty))) 

    implicit val paperViewDecoder: Decoder[PublishedPaperView] = Decoder.instance(
    cursor => 
     for { 
     id <- cursor.downField("id").as[PaperId] 
     paper <- cursor.downField("paper").as[Paper] 
    } yield PublishedPaperView(id, paper) 
) 
相关问题