Custom deserialization for class Queries(val pairs: Map[String, Seq[String]])
asarkar opened this issue · comments
How do I deserialize this class?
class Queries(val pairs: Map[String, Seq[String]])
I've something along the lines of the following:
override def read(yaml: YamlValue): Queries = {
Try(yaml.asYamlObject.getFields(
YamlString("queries")
) match {
case Seq(YamlObject(m)) => ???
})
}
But not sure how to interpret m
. There doesn't seem to be a YamlMap
class to use.
This seems to be working. Do you've any suggestions to make this better?
object QueriesYamlProtocol extends DefaultYamlProtocol {
implicit object QueriesYamlFormat extends YamlFormat[Queries] {
override def write(obj: Queries): YamlValue = ???
override def read(yaml: YamlValue): Queries = {
Try(yaml.asYamlObject.fields.map {
case (k, v) => (k.convertTo[String], v.prettyPrint.dropWhile(_ == UNIX.getString).split(",").map(_.trim).toSeq)
}.toMap) match {
case Success(m) => new Queries(m)
case Failure(ex) => ex.printStackTrace(System.err); new Queries(ImmutableMap())
}
}
}
}
I'm not sure I understand the YAML you are expecting for that class. Can you give an example of an YAML object you need to deserialize into a Queries
object?
The most common format for your class is something like:
pairs:
key1:
- a
- b
key2:
- c
- d
In that case, and if you can turn your class into a case class, your YamlFormat
is as simple as:
implicit val queriesYamlFormat = yamlFormat1(Queries)
Looking at your last QueriesYamlProtocol
, I believe you have something more on the lines of:
key1:
- a
- b
key2:
- c
- d
In that case, you can have:
implicit object QueriesYamlFormat extends YamlFormat[Queries] {
override def write(obj: Queries): YamlValue = ???
override def read(yaml: YamlValue): Queries =
Queries(yaml.convertTo[Map[String, Seq[String]]])
}
You can adapt this last format to modify the map after deserializing, if required by your domain.
@jcazevedo wrote:
Also, if you make your Queries class a case class, there's a handy helper to create a YamlFormat for your:
import net.jcazevedo.moultingyaml._
import net.jcazevedo.moultingyaml.DefaultYamlProtocol._
implicit val queriesYamlFormat = yamlFormat1(Queries)
This doesn't work when there's no field called pairs
. It'd be nice to have Mounting YAML fall back to the default values if exist, like the following:
case class Queries(val pairs: Map[String, Seq[String]] = Map())