Skip to content

Instantly share code, notes, and snippets.

@EdgeCaseBerg
Last active February 17, 2017 20:42
Show Gist options
  • Save EdgeCaseBerg/975d5c69e43a45e997c6876878707772 to your computer and use it in GitHub Desktop.
Save EdgeCaseBerg/975d5c69e43a45e997c6876878707772 to your computer and use it in GitHub Desktop.
This works even though my actual class doesn't for some reason. The real class fails on g and w :/
import io.circe._, io.circe.generic.semiauto._
import io.circe.parser.parse
import java.util.Locale
import cats.syntax.either._
object E extends Enumeration {
val x = Value("x")
}
trait JsonEncoderSupport {
import scala.language.implicitConversions
import io.circe._, io.circe.generic.semiauto._, io.circe.generic.decoding.DerivedDecoder, io.circe.generic.encoding.DerivedObjectEncoder
import cats.syntax.either._
/** Implicitly create a encoder for some type T
* @tparam T The type which to create implicits for
* @param encoder an implicit encoder for the type T, this implicit should be present automatically when extending this class
*/
implicit def encoder[T](implicit encoder: DerivedObjectEncoder[T]) = deriveEncoder[T]
/** Implicitly create a decoder for some type T
* @tparam T The type which to create implicits for
* @param decoder an implicit decoder for the type T, this implicit should be present automatically when extending this class
*/
implicit def decoder[T](implicit decoder: DerivedDecoder[T]) = deriveDecoder[T]
/** Explicitly create encoders and decoders for some type T
* @tparam T The type which to create encoders/decoders for
*/
def encoders[T](implicit derivedEncoder: DerivedObjectEncoder[T], derivedDecoder: DerivedDecoder[T]) = (encoder[T], decoder[T])
implicit val encodeLocale: Encoder[Locale] = Encoder.encodeString.contramap[Locale](_.toString)
implicit val decodeLocale: Decoder[Locale] = Decoder.decodeString.emap { str =>
Either.catchNonFatal(new Locale(str)).leftMap(t => "Locale")
}
implicit val ee = Encoder.enumEncoder(E)
implicit val ed = Decoder.enumDecoder(E)
}
case class B(
a: String,
b: String,
c: Option[String] = None,
d: Option[String] = None
)
object B extends JsonEncoderSupport {
implicit val (e,d) = encoders[B]
}
case class R(
a: Int,
b: Option[String] = None,
c: Option[String] = None
)
object R extends JsonEncoderSupport {
implicit val (e,d) = encoders[R]
}
case class RM(
a: Int,
b: Option[Boolean] = None,
c: Double,
d: String,
e: Option[String] = None
)
object RM extends JsonEncoderSupport {
implicit val (e,d) = encoders[RM]
}
case class S(
a: String,
b: E.Value,
c: Option[String] = None,
d: Option[B] = None
)
object S extends JsonEncoderSupport {
implicit val (e,d) = encoders[S]
}
case class P(
a: String,
b: Option[String] = None,
c: Option[String] = None,
d: Option[Int] = None,
e: String
)
object P extends JsonEncoderSupport {
implicit val (e,d) = encoders[P]
}
case class RS(
a: Int,
b: String
)
object RS extends JsonEncoderSupport {
implicit val (e,d) = encoders[RS]
}
case class RI(
a: Option[Int] = None,
b: Option[Int] = None,
c: Option[Double] = None,
d: Option[String] = None,
e: Option[String] = None,
f: Option[String] = None,
g: Option[String] = None
)
object RI extends JsonEncoderSupport {
implicit val (e,d) = encoders[RI]
}
case class RG(
a: Option[Int] = None,
b: Option[String] = None,
c: Int,
d: List[RI]
)
object RG extends JsonEncoderSupport {
implicit val (e,d) = encoders[RG]
}
case class RT(
a: Option[Int] = None,
b: Option[String] = None,
c: Option[E.Value] = None
)
object RT extends JsonEncoderSupport {
implicit val (e,d) = encoders[RT]
}
case class RN(
a: Option[Int] = None,
b: String,
c: Double,
d: Option[String] = None,
e: String,
f: Option[Double] = None,
g: Option[Int] = None
)
object RN extends JsonEncoderSupport {
implicit val (e,d) = encoders[RN]
}
case class TM(
a: Option[Int] = None,
b: Option[Int] = None,
c: Option[String] = None,
d: Option[Boolean] = None
)
object TM extends JsonEncoderSupport {
implicit val (e,d) = encoders[TM]
}
case class DTM(
a: Double,
b: Option[String] = None
)
object DTM extends JsonEncoderSupport {
implicit val (e,d) = encoders[DTM]
}
case class CM(
a: String,
b: String,
c: Double,
d: String
)
object CM extends JsonEncoderSupport {
implicit val (e,d) = encoders[CM]
}
case class Top(
a: String,
b: String,
c: String,
d: String,
e: Locale,
f: Boolean,
g: Option[String] = None,
h: String,
i: Option[String] = None,
j: Option[String] = None,
k: Option[String] = None,
l: String,
m: String,
o: Int,
p: String,
q: Int,
r: String,
s: Int,
t: Option[String] = None,
u: Option[Int] = None,
v: Option[String] = None,
w: Option[Int] = None,
x: R,
y: B,
z: RM,
aa: RM,
bb: List[S],
cc: List[P],
dd: List[String],
ee: Seq[RS],
ff: List[RG],
gg: Option[List[RT]] = None,
hh: List[RN],
ii: List[TM],
jj: Option[String] = None,
kk: Option[DTM] = None,
ll: Option[CM] = None,
mm: Option[String] = None,
nn: Option[String] = None,
oo: Option[String] = None,
pp: Option[String] = None,
qq: Option[String] = None,
rr: Option[String] = None,
ss: Option[String] = None
)
object Top extends JsonEncoderSupport {
implicit val (e,d) = encoders[Top]
}
val s = """
{
"j": "",
"f": true,
"l": "",
"r": "",
"i": "Bakasteflower",
"v": null,
"s": 6,
"k": "Arverbrownrice.",
"t": null,
"q": 70,
"p": "",
"u": 1174,
"o": 20,
"m": "",
"a": "REC0001153",
"d": "recipe",
"e": "en",
"g": null,
"w": null,
"b": "htiflower/",
"c": "",
"h": "BakeCauliflower",
"z": {
"a": 37,
"c": 0,
"d": "1ackages",
"e": " 1ackages"
},
"aa": {
"a": 37,
"c": 0,
"d": "1ackages",
"e": " 1ackages"
},
"dd": [],
"ii": [],
"bb": [{
"a": "R2464",
"b": "x"
}, {
"a": "R2464",
"b": "x"
}],
"jj": "102683894",
"y": {
"a": "BR0000002",
"b": "brand"
},
"cc": [],
"ff": [{
"a": 1294,
"b": "group1",
"c": 1,
"d": [{
"a": 298,
"b": 1,
"c": 1,
"d": "1poages",
"e": "hney",
"f": "",
"g": "1oney"
}, {
"a": 132,
"b": 2,
"c": 1,
"d": "1kages",
"e": "ditard",
"f": "",
"g": "1tard"
}]
}],
"mm": "2017-02-08T20:47:56",
"gg": [],
"ee": [{
"a": 1,
"b": "Pcrus."
}, {
"a": 2,
"b": "Arranulifloxture."
}, {
"a": 3,
"b": "Bakeesirepper."
}],
"x": {
"a": 1,
"b": "x",
"c": ""
},
"hh": [{
"a": 1,
"b": "Cies",
"c": 429,
"d": "429.0 µg Folate",
"e": "kJ",
"f": 1,
"g": 3
}, {
"a": 2,
"b": "Cabohytal",
"c": 42,
"d": "42.0 g",
"e": "g",
"f": 1,
"g": 4
}],
"ss": "foo bar"
}
"""
val p = parse(s)
p.right.get.as[Top]
@EdgeCaseBerg
Copy link
Author

If you remove the implicit from the two def's in the trait JsonEncoderSupport encoder and decoder then it will work and you can parse the value as Top.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment