When materializing a GenCodec
for sealed hierarchy with @flatten
annotation, you can use this
annotation on one of case classes or objects to mark it as the default one.
Changes the serialization format used by GenCodec
s automatically derived for sealed hierarchies.
Changes the serialization format used by GenCodec
s automatically derived for sealed hierarchies.
The format is changed from "nested" to "flat".
@flatten sealed trait Value case class Numeric(int: Int) extends Value case class Textual(string: String) extends Value object Value { implicit val codec: GenCodec[Value] = GenCodec.materialize[Value] }
Without flatten annotation, the "nested" format is used, e.g. when Numeric(42)
would be encoded to JSON
as:
{"Numeric": {"int": 42}}
but when flatten annotation is applied on sealed trait/class, then it changes to:
{"_case": "Numeric", "int": 42}
The "_case" field name can be customized with annotation parameter
May be used on members of objects, case classes or any types having companion object with case class
like apply
and unapply
/unapplySeq
methods in order to add additional, generated fields to data serialized by
auto-materialized GenCodec
s.
May be used on members of objects, case classes or any types having companion object with case class
like apply
and unapply
/unapplySeq
methods in order to add additional, generated fields to data serialized by
auto-materialized GenCodec
s.
case class User(id: Long, login: String) { @generated def upperLogin: String = login.toUpperCase } object User { implicit val codec: GenCodec[User] = GenCodec.materialize[User] }
This annotation may be applied on val
s, var
s and def
s. When applied on a def
, it must be either parameterless
(no parameter lists or empty parameter list) or accept only implicit parameters, provided that all the implicit values
are available in the scope where GenCodec
is materialized (implicit values will be "baked in" the codec).
NOTE: @generated
annotation may be defined on any level of inheritance hierarchy - it will be inherited
from implemented and overridden members.
Can be used on case class fields and classes in sealed hierarchy to instruct automatically derived GenCodec
to use particular name instead of just using parameter or class name.
Can be used on case class fields and classes in sealed hierarchy to instruct automatically derived GenCodec
to use particular name instead of just using parameter or class name.
For example:
sealed trait Base @name("STH") case class Something(@name("dbname") paramname: Int) extends Base object Base { implicit codec = GenCodec.auto[Base] }
GenCodec.write[Base](someOutput, Something(42))
would write an object
{"STH": {"dbname": 42}}
instead of {"Something": {"paramname": 42}}
.
NOTE: @name
annotation may be defined on any level of inheritance hierarchy.
For instance, if a case class field overrides a method of some base trait, the @name
annotation may
be used on that method and will affect the case class field.
To be used in conjunction with flatten.
To be used in conjunction with flatten.
It can be applied on one or more of case class fields in a sealed hierarchy to instruct the
auto-materialized GenCodec
that this particular field may appear before _case
field in the serialized format
during reading.
@flatten sealed trait Base case class FirstCase(@outOfOrder tag: String, int: Int) extends Base case class SecondCase(dbl: Double) extends Base object Base { implicit val codec: GenCodec[Base] = GenCodec.materialize[Base] }
The following JSON (assuming this is the representation used) would correctly deserialize as
FirstCase("someTag", 42)
:
{"tag": "someTag", "_case": "FirstCase", "int": 42}
Field annotated with @outOfOrder
annotation doesn't have to be present in every case class, but if it is present,
all case classes must annotate it and give it exactly the same type. The annotation may also be inherited, e.g.
@flatten sealed trait Base { @outOfOrder def tag: String } case class FirstCase(tag: String, int: Int) extends Base case class SecondCase(tag: String, dbl: Double) extends Base
If some case class field has default value, you can use this annotation on this field to instruct an
automatically derived GenCodec
to not persist the value of that field if it's equal to the default value.
If some case class field has default value, you can use this annotation on this field to instruct an
automatically derived GenCodec
to not persist the value of that field if it's equal to the default value.
For example:
case class Something(str: String, @transientDefault int: Int = 42) object Something { implicit val codec = GenCodec.auto[Something] }
GenCodec.write(someOutput, Something("lol", 10))
would yield object {"str": "lol", "int": 10}
but
GenCodec.write(someOutput, Something("lol", 42))
would yield object {"str": "lol"}
because the value of int
is the same as the default value.
Can be used on case classes with exactly one field to instruct automatically generated GenCodec
that the
class is a "transparent wrapper" and should be serialized to the same representation as the value of its sole
field.
When materializing a
GenCodec
for sealed hierarchy with@flatten
annotation, you can use this annotation on one of case classes or objects to mark it as the default one. If during deserialization the codec is unable to find the_case
field and determine the case class/object to deserialize, it will try to deserialize the data to the class/object marked with this annotation.This is useful for retaining backwards compatibility with serialized format when refactoring code and replacing a simple case class with a sealed hierarchy.