Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Circe encoder for generic case class with default parameters

Tags:

json

scala

circe

I am looking to provide JSON encoders for the following case class:

import io.circe.generic.extras.Configuration

final case class Hello[T](
    source: String, 
    version: Int = 1,
    data: T
)

object Hello {
  implicit val configuration: Configuration = Configuration.default.withDefaults
}

I would ordinarily call deriveEncoder[A] in the companion object, but that doesn't work here as there is no reference or Encoder for T available here.

The Hello type will be provided to clients as a library, so I would like to do as much of the boilerplate as possible within this type rather than depend on client code providing the encoder and decoder. Is there an idiomatic solution to this with circe so that clients provide an encoder/decoder for T and this gets used to derive the encoder/decoder for Hello[T]?

like image 297
Rich Ashworth Avatar asked Jan 28 '19 10:01

Rich Ashworth


1 Answers

Yes, you need to add a context bound requiring an implicit encoder to be present for any type T:

import io.circe.gemeric.semiauto._

final case class Hello[T](
  source: String,
  version: Int = 1,
  data: T
)

object Hello {
  implicit def helloEncoder[T: Encoder]: Encoder[Hello[T]] = deriveEncoder
}

Such that when the user creates their own Hello[Foo] type, they'll have to make sure that Foo has its own encoder.

like image 197
Yuval Itzchakov Avatar answered Oct 17 '22 06:10

Yuval Itzchakov