2016-12-16 6 views
5

値クラスのエンコーダインスタンスを派生させたいと考えています。 semiautoメカニズムでは、ネストされたクラスを派生することができません。CirceでのAnyValタイプの一般的な導出

イメージアンモナイトシェルで次の場合クラス構造

{ 
    case class Recipient(email: Recipient.Email, name: Recipient.Name) 

    object Recipient { 
    case class Email(value: String) extends AnyVal 
    case class Name(value: String) extends AnyVal 
    } 
} 

Recipient.Email("[email protected]").asJson(deriveEncoder[Recipient.Email]) 
Json = { 
    "value" : "[email protected]" 
} 
に予想通り

load.ivy("io.circe" %% "circe-core" % "0.6.1") 
load.ivy("io.circe" %% "circe-generic" % "0.6.1") 

import io.circe._ 
import io.circe.generic.semiauto._ 
import io.circe.syntax._ 

すぐEmail結果ためのデコーダを導出する(また、レシピエントケースクラスを追加)

Encoder[Recipient]が得られない

deriveDecoder[Recipient] 

could not find Lazy implicit value of type 
io.circe.generic.decoding.DerivedDecoder[$sess.cmd5.Recipient] 

私は何をしたいのラップ型を返すEncoder[Recipient.Email]を導出しています。私がコーデックを明示的に派生させれば、この小さな作品が動作します。

import shapeless.Unwrapped 

implicit def encodeAnyVal[W <: AnyVal, U](
     implicit unwrapped: Unwrapped.Aux[W, U], 
       encoderUnwrapped: Encoder[U]): Encoder[W] = { 
     Encoder.instance[W](v => encoderUnwrapped(unwrapped.unwrap(v))) 
} 

Recipient.Email("[email protected]").asJson(encodeAnyVal[Recipient.Email, String]) 
res11: Json = "[email protected]" 

それでも私はEncoder[Recipient]

implicit val emailEncoder: Encoder[Recipient.Email] = encodeAnyVal[Recipient.Email, String] 
implicit val nameEncoder: Encoder[Recipient.Name] = encodeAnyVal[Recipient.Name, String] 

deriveDecoder[Recipient] 
cmd14.sc:1: could not find Lazy implicit value of type io.circe.generic.decoding.DerivedDecoder[$sess.cmd5.Recipient] 

は誰でも似たような行っている導き出すことはできませんか?事前に

おかげで、 Muki

答えて

0

あなたが代わりにバインド型の暗黙の証人のインスタンスを追加する必要があります。このようなもので終わるつもり:

implicit def encodeAnyVal[W, U](
     implicit ev: W <:< Anyval, 
       unwrapped: Unwrapped.Aux[W, U], 
       encoderUnwrapped: Encoder[U]): Encoder[W] = { 
     Encoder.instance[W](v => encoderUnwrapped(unwrapped.unwrap(v))) 
} 
関連する問題