Let's assume I have a case class with the following setup:
case class Place(id:java.util.UUID, name:String)
I can write a (working!) serializer for this type as follows:
class placeSerializer extends CustomSerializer[Place]( format => (
{
case JObject(JField("id", JString(s)) :: JField("name",JString(x)) :: Nil ) =>
Place(UUID.fromString(s), x)
},
{
case x:Place =>
JObject(
JField("id", JString(x.id.toString())) ::
JField("name", JString(x.name)) :: Nil)
}
)
)
But assuming my case class eventually has a lot more fields, this could lead to me enumerating the entire structure of the object with the AST, creating something that's very verbose just to encode primitives.
json4s appears to have field serializers that can act only on specific fields, with boilerplate methods included to easily transform names and discard fields. These, however, have the following signature for their serialize
and deserialize
partial functions:
case class FieldSerializer[A: Manifest](
serializer: PartialFunction[(String, Any), Option[(String, Any)]] = Map(),
deserializer: PartialFunction[JField, JField] = Map()
)
Since JField
(the type that representes a key -> val from the json) is its own type and not a subclass of JValue
, how can I combine these two types of serializers to properly encode the id
key by its name to a UUID
, while maintaining the default handling of the other fields (which are primitive datatypes).
Essentially I'd like a format chain that understands the field within Place
is a UUID, without having to specify AST structure for all the fields that DefaultFormats
can already handle.
What I'm looking for specifically is to mimic a pattern similar to the JSONEncoder
and JSONDecoder
interfaces in python, which can use the key name as well as value type to determine how to handle the marshalling for the field.