【问题标题】:Decode config to case class with pureconfig with default values使用具有默认值的 pureconfig 将配置解码为案例类
【发布时间】:2021-08-28 15:22:30
【问题描述】:

假设我有以下配置:

{
  “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,因为列表的第二个对象中没有其他值键) 有办法吗?

【问题讨论】:

  • 那是什么配置?看起来不像 HOCON
  • 抱歉,忘记在配置中的变量名和尾随逗号周围添加引号。写得非常快,现在编辑成看起来像一个普通的 application.conf 文件。是HOCON ????
  • 抱歉,已在说明中修复

标签: scala pureconfig


【解决方案1】:

您可以在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]

【讨论】:

  • 非常感谢,成功了!我有一个问题 - 有没有更方便的方法?就我而言,我有一个更复杂的配置,并且只有一个字段应该以这种方式处理。有没有办法为特定班级引入自定义阅读之类的东西?
  • 是的,有一种方法可以为特定的班级定制阅读:像上面一样写一个定制的ConfigReader。关于“更复杂的配置”的事情,我没有看到问题。如果您将其声明为case class MoreComplexConfig(config: GenConfig[Int]),那么一切都会正常进行。 MoreComplexConfig 不需要类型参数——我觉得很方便。
  • 非常感谢!我试图写这样的东西几个小时,最后放弃了?。现在一切正常
  • 在这种情况下,您可能希望将我的答案标记为已接受。
  • 谢谢,这是我关于stackoverflow的第一个问题,不知道如何标记为已接受?
猜你喜欢
  • 1970-01-01
  • 2013-05-27
  • 1970-01-01
  • 2018-05-03
  • 2022-01-27
  • 1970-01-01
  • 2015-01-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多