默认情况下,pureconfig 不提供读取Any 的方法。如果您想阅读特定的类Any,那么您可以在该类的上下文中为Any 定义一个编解码器:
case class Filter(field: String, operator: String, variable: Any)
implicit val readFilter = {
implicit val readAny = new ConfigReader[Any] {
def from(config: ConfigValue): Either[ConfigReaderFailures, Any] = {
Right(config.unwrapped())
}
}
ConfigReader[Filter]
}
然后你可以阅读Filter
val config = ConfigFactory.parseString(
"""
{
field: "foo"
operator: "bar"
variable: []
}
""")
println(pureconfig.loadConfig[Filter](config))
// will print Right(Filter(foo,bar,[]))
unwrapped 将ConfigValue 递归转换为Any。
所以答案是肯定的,如果可能的话,告诉pureconfig如何读取Any。
pureconfig 默认不为Any 提供编解码器的原因是因为Any 是Scala 中所有类的祖先,不可能为任何东西(例如数据库连接)创建编解码器。当您知道您需要一组受限类型(如您列出的类型)时,您可以将所有内容包装在一个副产品中:
sealed abstract class MySupportedType
final case class MyInt(value: Int) extends MySupportedType
final case class MyDouble(value: Double) extends MySupportedType
final case class MyListOfString(value: List[String]) extends MySupportedType
final case class MyListOfInt(value: List[Int]) extends MySupportedType
final case class Filter2(field: String, operator: String, variable: MySupportedType)
然后使用默认方式提取联积值或MySupportedType的自定义编解码器
val config = ConfigFactory.parseString(
"""
{
field: "foo"
operator: "bar"
variable: {
type: mylistofint
value: []
}
}
""")
println(pureconfig.loadConfig[Filter2](config))
// will print Right(Filter2(foo,bar,MyListOfInt(List())))
使用联积而不是 Any 会限制 variable 可以拥有的可能值,如果您正在做的事情有问题,让编译器帮助您。