jcazevedo / moultingyaml

Scala wrapper for SnakeYAML

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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())