I can not deal with usage of circe
to encode instance of FL
class to JSON.
I provided two custom encoders - both for CS
and RS
classes. However, still during compilation I got:
could not find implicit value for parameter encoder: io.circe.Encoder[FL]
when I try to compile:
import io.circe.{Encoder, Json}
import io.circe.generic.extras.auto._
import io.circe.syntax._
FL(List.empty).asJson
implicit val rsEncoder: Encoder[RS] = Encoder.instance[RS] { x =>
Json.obj(
)
}
implicit val csEncoder: Encoder[CS] = Encoder.instance[CS] { x =>
Json.obj(
)
}
sealed trait A {
def s: Int
}
object A {
case class RS(s: Int, d: Double) extends A
case class CS(s: Int, l: Double) extends A
}
case class FSI[T <: A](sts: T)
final case class E(
segs: Seq[FSI[_ <: A]] = Seq.empty,
)
final case class FL(es: List[List[E]])
The only way I see is trial of implementation of encoder at FL
class level - however I would like to avoid it as this class contain more elements (however they are not problematin in terms of encoding).
Could you help me to do/workaround it? Or maybe there exist theoretical reason it is not possible.
I played around with your code and I think there are two things that are throwing off Circe:
A
you're encodingSeq[_ <: A]
(not automatically at least), so you need to just go for Seq[A]
(which I don't think should limit you in practice, but happy to stand corrected)The following seems to work as expected:
import io.circe.{Encoder, Json}
import io.circe.generic.extras.auto._
import io.circe.syntax._
import io.circe.generic.extras.Configuration
implicit val genDevConfig: Configuration =
Configuration.default.withDiscriminator("type")
sealed trait A {
def s: Int
}
object A {
case class RS(s: Int, d: Double) extends A
case class CS(s: Int, l: Double) extends A
}
case class FSI[T <: A](sts: T)
final case class E(
segs: Seq[FSI[A]] = Seq.empty,
)
final case class FL(es: List[List[E]])
FL(List.empty).asJson.noSpaces
FL(List(List(E(List(FSI(A.RS(1, 4.2))))))).asJson.noSpaces
Notice that I didn't even have to include the custom encoders for RS
and CS
.
You can play around with this code here on Scastie (I configured to use Scala 2.13 and Circe 0.14.3, which based on your original post it seems like going in the direction of your current dependencies).
If you want to use the custom encoders, you have to manually dispatch to each type by explicitly having an Encoder[A]
as in the following snippet:
import io.circe.{Encoder, Json}
import io.circe.generic.extras.auto._
import io.circe.generic.extras.Configuration
import io.circe.syntax._
implicit val config: Configuration = Configuration.default
implicit val rsEncoder: Encoder[A.RS] = Encoder.instance[A.RS] { x =>
Json.obj(
)
}
implicit val csEncoder: Encoder[A.CS] = Encoder.instance[A.CS] { x =>
Json.obj(
)
}
implicit val encodeA: Encoder[A] = Encoder.instance[A] {
case rs: A.RS => rs.asJson
case cs: A.CS => cs.asJson
}
sealed trait A {
def s: Int
}
object A {
case class RS(s: Int, d: Double) extends A
case class CS(s: Int, l: Double) extends A
}
case class FSI[T <: A](sts: T)
final case class E(
segs: Seq[FSI[A]] = Seq.empty
)
final case class FL(es: List[List[E]])
FL(List.empty).asJson.noSpaces
FL(List(List(E(List(FSI(A.RS(1, 4.2))))))).asJson.noSpaces
This example is also available on Scastie. Note that in this case you'll still have to use some form of discriminator if you need to parse those JSON objects back in the same types.
I wrote this using information from the Circe documentation about ADT encoding.