2016-12-16 6 views
5

Я хочу получить экземпляры Encoder для классов значений. С механизмом semiauto я не могу вывести вложенные классы.Общий вывод типов AnyVal с Circe

Изображения следующего класс случая структура

{ 
    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 
    } 
} 

В аммонитовых оболочках (добавить классы регистра получателей)

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 результатов, как и ожидался, в

Recipient.Email("[email protected]").asJson(deriveEncoder[Recipient.Email]) 
Json = { 
    "value" : "[email protected]" 
} 

Получение 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))) 
}