Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom deserialization for class Queries(val pairs: Map[String, Seq[String]]) #18

Open
asarkar opened this issue Nov 5, 2016 · 3 comments

Comments

@asarkar
Copy link

asarkar commented Nov 5, 2016

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.

@asarkar
Copy link
Author

asarkar commented Nov 5, 2016

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

@ruippeixotog
Copy link
Collaborator

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.

@asarkar
Copy link
Author

asarkar commented Nov 5, 2016

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants