2017-01-09 46 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) 
) 
相關問題