【问题标题】:Can't get pureconfig to deserialize nested case classes无法让 pureconfig 反序列化嵌套案例类
【发布时间】:2019-08-11 12:11:10
【问题描述】:

我正在尝试使用 pureconfig 对嵌套案例类进行反序列化,但代码无法编译。我有以下几点:

import com.typesafe.config.{Config, ConfigFactory}
import pureconfig.error.ConfigReaderFailures
import pureconfig.generic.ProductHint
import pureconfig.generic.semiauto._
import pureconfig.{CamelCase, ConfigFieldMapping}

class ClassAReader {
  implicit def classAHint = ProductHint[ClassA](ConfigFieldMapping(CamelCase, CamelCase))
  implicit def classBHint = ProductHint[ClassB](ConfigFieldMapping(CamelCase, CamelCase))

  implicit val classAReader = deriveReader[ClassA]
  implicit val classBReader = deriveReader[ClassB]

  def read(config: Config): ClassA = pureconfig.loadConfig[ClassA](config.getConfig("foo")).fold((a: ConfigReaderFailures) => throw new Exception(), conf => conf)

  val config = ConfigFactory.parseString("""{ a: { one: 1, two: "foo" }, b: { one: 2, two: "bar" }, 42 }""")
  val reader = new ClassAReader

  reader.read(config)
}

case class ClassA(a: ClassB, b: ClassB, other: Int)

case class ClassB(one: Int, two: String)

但我遇到了编译问题。有谁知道我做错了什么?

【问题讨论】:

    标签: scala nested deserialization pureconfig


    【解决方案1】:

    您应该始终注释隐式定义,尤其是在这种情况下,ClassA 的读者推导取决于 ClassB 的推导,等等。以下只是有效的:

    import com.typesafe.config.{Config, ConfigFactory}
    import pureconfig.ConfigReader
    import pureconfig.error.ConfigReaderFailures
    import pureconfig.generic.ProductHint
    import pureconfig.generic.semiauto._
    import pureconfig.{CamelCase, ConfigFieldMapping}
    
    class ClassAReader {
      implicit def classAHint: ProductHint[ClassA] =
        ProductHint[ClassA](ConfigFieldMapping(CamelCase, CamelCase))
      implicit def classBHint: ProductHint[ClassB] =
        ProductHint[ClassB](ConfigFieldMapping(CamelCase, CamelCase))
    
      implicit val classAReader: ConfigReader[ClassA] = deriveReader[ClassA]
      implicit val classBReader: ConfigReader[ClassB] = deriveReader[ClassB]
    
      def read(config: Config): Either[ConfigReaderFailures, ClassA] =
        pureconfig.loadConfig[ClassA](config)
    }
    
    case class ClassA(a: ClassB, b: ClassB, other: Int)
    case class ClassB(one: Int, two: String)
    

    然后:

    scala> val config = ConfigFactory.parseString(
         |   """{ a: { one: 1, two: "foo" }, b: { one: 2, two: "bar" }, other: 42 }"""
         | )
    config: com.typesafe.config.Config = Config(SimpleConfigObject({"a":{"one":1,"two":"foo"},"b":{"one":2,"two":"bar"},"other":42}))
    
    scala> val reader = new ClassAReader
    reader: ClassAReader = ClassAReader@589da48f
    
    scala> reader.read(config)
    res1: Either[pureconfig.error.ConfigReaderFailures,ClassA] = Right(ClassA(ClassB(1,foo),ClassB(2,bar),42))
    

    (请注意,我还必须将 read 调用移出类 - 否则构造函数会调用自身,您将得到 Stack Overflow。我还修复了示例,以便实际解码。)

    【讨论】:

      猜你喜欢
      • 2013-10-12
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-05
      • 2020-10-08
      • 1970-01-01
      相关资源
      最近更新 更多