scalahoconpureconfig

Using pureconfig to read tuples encoded as a list or array


I'd like to use the PureConfig library to read a list of tuples. That is, I'd like to read

{
  foo: [
    [1, 1.0, "Good job!"]
    [2, 2.0, "Excellent job!"]
    [3, 0.0, "Please play again."]
  ]
}

as a

case class Wrapper(foo:Vector[(Int, Double, String)])

A PureConfig issue from 2018 is tantalizing:

Think of tuples as containers instead; a pair holds two values with possibly different types and can be loaded as an array from a config, like [A, B]. You'll find plenty of use cases where you want to load such a structure but for some reason don't want to define a new object - for example, you can load a list of histogram counters (a List of (String, Int) entries) encoding it in the config as [[a, 1], [b, 3], [c, 2], ...].

but I haven't been able to figure out how to actually do it.

On the theory that I should walk before running, I've written the following to attempt to read just a single tuple, encoded as a list/array:

implicit val tReader: ConfigReader[(Int, Double, String)] = {
   ConfigReader[Int].zip(ConfigReader[Double]).zip(ConfigReader[String]).map(x => (x._1._1, x._1._2, x._2))
}
case class Wrapper(foo: (Int, Double, String))
val mi: Result[Wrapper] =
   ConfigSource.fromConfig(ConfigFactory.parseString("""foo: [5, 1.0, "hello" ]""")).load[Wrapper]

It fails when it encounters the list notation: [...]

Suggestions welcome.


Solution

  • The pureconfig-magnolia module does what you need. It's alternative of the generic module, but unlike it, that supports tuples. Once you added it in your build, all you need to do is add the corresponded import and create a reader for your wrapper class.

      import pureconfig.module.magnolia.auto.reader.exportReader
    
      case class Wrapper(foo: (Int, Double, String))
    
      implicit val wrapperReader: ConfigReader[Wrapper] =
        ConfigReader.exportedReader
    
      val mi: Result[Wrapper] =
        ConfigSource
          .fromConfig(ConfigFactory.parseString("""foo: [5, 1.0, "hello" ]"""))
          .load[Wrapper]
    

    There you can find a README file and tests of this module: https://github.com/pureconfig/pureconfig/tree/master/modules/magnolia