Reputation: 31526
I have written this code to read and write josn using circe
import io.circe._, io.circe.generic.auto._, io.circe.parser._, io.circe.syntax._
case class Foo(i: Int)
val f = Foo(10)
val json = f.asJson.toString
val t1 = decode[Foo](json)
this works very well. But if I create a normal class Bar
class Bar { var i : Int = 0 }
decode[Bar](json)
Now I get error
could not find implicit value for evidence parameter of type io.circe.Decoder[$sess.cmd25.Bar]
So is it possible to work with normal classes and decode them from json using Circe?
Upvotes: 3
Views: 1490
Reputation: 4481
Little addition to LMeyer answer.
If your Bar
class quite simple, you can write encoder
and decoder
shortly using some forProduct
functions:
import io.circe.{Codec, Decoder, Encoder}
import io.circe.parser._
import io.circe._
class Bar {
val i: Int = 0
val j: Option[String] = Some("value")
override def toString: String =
s"Bar(i: $i, j: $j)"
}
object Bar {
implicit val encoder: Encoder[Bar] =
Encoder.forProduct2[Bar, Int, Option[String]]("i", "j")(
bar => (bar.i, bar.j)
)
implicit val decoder: Decoder[Bar] =
Decoder.forProduct2[Bar, Int, Option[String]]("i", "j")(
(iValue, jValue) =>
new Bar {
override val i = iValue;
override val j = jValue
}
)
implicit val codec: Codec[Bar] =
Codec.forProduct2[Bar, Int, Option[String]]("i", "j")(
(iValue, jValue) =>
new Bar {
override val i = iValue;
override val j = jValue
}
)(bar => (bar.i, bar.j))
}
val json =
"""{"i":42,"j":"Hello"}""".stripMargin
val bar = decode[Bar](json).getOrElse(throw new Exception("Decoding failed"))
// bar: Bar = Bar(i: 42, j: Some(Hello))
println(
Printer.noSpaces
.print(Encoder[Bar].apply(bar))
)
// {"i":42,"j":"Hello"}
println(
Printer.noSpaces
.print(Encoder[Bar].apply(bar)) == json
)
// true
Upvotes: 0
Reputation: 2631
With io.circe.generic.auto._
, you're using Circe's automatic generic derivation, which is backed by Shapeless's LabelledGeneric
typeclass. LabelledGeneric
only works with product types like tuples and case classes. That's why your seeing this error, because Circe's auto mode could not automatically derive a Decoder instance for your plain class. What you can do is manually implement a decoder for your class (see custom encoders/decoders part).
Upvotes: 6