2017-10-17 12 views
0

을 감안할 때 :봉인 된 특성 계층 구조에 DecodeJson 작성?

import argonaut._ 
import Argonaut._ 
import ArgonautShapeless._ 

sealed trait Parent 
case class Foo(x: Int) extends Parent 
case class Bar(y: String) extends Parent 

내가 정의하는 DecodeJson[Parent]을 시도 : argonaut.DecodeResult는 불변이기 때문에 실패 그러나

implicit val parentDecodeJson: DecodeJson[Parent] = 
    DecodeJson(c => c.focus.objectFields match { 
     case Some("x" :: _) => implicitly[DecodeJson[Foo]].decode(c) 
     case _    => implicitly[DecodeJson[Bar]].decode(c) 
    }) 

. 깨끗한 방법은

scala> Json.obj(("x", jNumber(42))).as[Parent] 
res2: argonaut.DecodeResult[Parent] = DecodeResult(Right(Foo(42))) 

scala> Json.obj(("y", jString("hi!"))).as[Parent] 
res3: argonaut.DecodeResult[Parent] = DecodeResult(Right(Bar(hi!))) 

있습니까 : 작동하는 것 같다

implicit val parentDecodeJson: DecodeJson[Parent] = 
    DecodeJson(c => c.focus.objectFields match { 
     case Some("x" :: _) => implicitly[DecodeJson[Foo]].decode(c).flatMap{a => DecodeResult.ok(a)} 
     case _  => implicitly[DecodeJson[Bar]].decode(c).flatMap{a => DecodeResult.ok(a)} 
    }) 

:

<console>:42: error: type mismatch; 
found : argonaut.DecodeResult[Foo] 
required: argonaut.DecodeResult[Parent] 
Note: Foo <: Parent, but class DecodeResult is invariant in type A. 
You may wish to define A as +A instead. (SLS 4.5) 
       case Some("x" :: _) => implicitly[DecodeJson[Foo]].decode(c) 
                    ^
<console>:43: error: type mismatch; 
found : argonaut.DecodeResult[Bar] 
required: argonaut.DecodeResult[Parent] 
Note: Bar <: Parent, but class DecodeResult is invariant in type A. 
You may wish to define A as +A instead. (SLS 4.5) 
      case _  => implicitly[DecodeJson[Bar]].decode(c) 
                  ^

그래서, 나는이 함께했다?

println(EncodeJson.of[Parent].encode(Bar("a")))//{"Bar":{"y":"a"}} 
println(EncodeJson.of[Parent].apply(Bar("a")))//{"Bar":{"y":"a"}} 
println(Bar("a").asJson)//{"y":"a"} 
println((Bar("a"): Parent).asJson)//{"Bar":{"y":"a"}} 
println("{\"Bar\":{\"y\":\"a\"}}".decode[Parent])//Right(Bar(a)) 
println("{\"Bar\":{\"y\":\"a\"}}".decodeOption[Parent])//Some(Bar(a)) 

을 아니면 내가 당신의 목표를 오해 않습니다

+1

적어도 README에 나와있는 의 내용대로 작동합니다 (https://github.com/alexarchambault/argonaut-shapeless) –

+0

방법에 대해 알아 보려면 https://stackoverflow.com/questions/39108841을 참조하십시오./json-structure-on-json-structure를 기반으로 한 j-sealed-trait-in-argonaut – tkachuko

답변

0

당신은 당신의 자신의 implicits를 정의 할 필요가 없습니다?