General Inference of AnyVal Types with Circe

I want to get Encoder instances for value classes. With the semiauto mechanism semiauto I cannot output nested classes.

Display the following structure for the case class

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

In an ammonite shell (also add recipient class classes)

 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._ 

Now we get a decoder for Email results, as expected in

 Recipient.Email(" ab@cd.com ").asJson(deriveEncoder[Recipient.Email]) Json = { "value" : " ab@cd.com " } 

Getting Encoder[Recipient] Doesn't Work

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

I would like to draw the output of Encoder[Recipient.Email] , which returns a wrapped type. This little piece works if I get the codec explicitly.

 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(" ab@cd.com ").asJson(encodeAnyVal[Recipient.Email, String]) res11: Json = " ab@cd.com " 

However, I cannot get 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] 

Has anyone done something like this?

Thanks in advance, Muki

+5
source share
1 answer

You must add an implicit witness instance instead of a type binding. The result is something like this:

 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))) } 
0
source

Source: https://habr.com/ru/post/1261413/


All Articles