使用具有默认值的 pureconfig 将配置解码为 case class

Decode config to case class with pureconfig with default values

假设我有以下配置:

{
  “default-value”:5,
  “some-seq”: [
    {“some-other-value”:100},
    {“foo”:”bar”},
    {“some-other-value”:1500}
  ]
}

我希望它被解码为大小写 类:

case class Config(defaultValue: Int, someSeq: Seq[SomeInteger])
case class SomeInteger(someOtherValue: Int)

以便它创建 Config(5, Seq(SomeInteger(100), SomeInteger(5), SomeInteger(1500))) (第二个是 5,因为列表的第二个对象中没有其他值键) 有办法吗?

您可以在 SomeIntegerConfig 中添加类型参数来指定 someOtherValue 的类型。然后创建一个 ConfigReader[Config[Option[Int]]] 并使用 map 方法应用默认值:

case class Config[A](defaultValue: Int, someSeq: Seq[SomeInteger[A]])
object Config {
  private def applyDefault(config: Config[Option[Int]]): Config[Int] =
    config.copy(
      someSeq = config.someSeq.map(i =>
        i.copy(
          someOtherValue = i.someOtherValue.getOrElse(config.defaultValue))))

  implicit val reader: ConfigReader[Config[Int]] =
    deriveReader[Config[Option[Int]]]
      .map(applyDefault)
}
case class SomeInteger[A](someOtherValue: A)
object SomeInteger {
  implicit val reader: ConfigReader[SomeInteger[Option[Int]]] =
    deriveReader[SomeInteger[Option[Int]]]
}

不幸的是,这意味着您需要在所有地方都写上 Config[Int],而不仅仅是 Config。但这可以通过将 Config 重命名为 e 轻松解决。 G。 GenConfig 并添加类型别名:type Config = GenConfig[Int].