Часть моей конфигурации содержит произвольный JSON. Я хочу десериализовать этот JSON как JValue для дальнейшей обработки.
Однако ConfigSource.load
жалуется, что ключ type
не найден.
Тестовый код:
import org.json4s.JsonAST.JValue
import pureconfig.ConfigReader.Result
import pureconfig._
import pureconfig.generic.auto._
object PureConfig2JValue extends App {
case class Config(json: JValue)
val source: ConfigObjectSource = ConfigSource.string("{ \"json\": { \"test\": \"test\" } }")
val loadedSource: Result[Config] = source.load[Config]
println(loadedSource)
}
Вывод:
Left(ConfigReaderFailures(ConvertFailure(KeyNotFound(type,Set()),None,json),List()))
Как я могу заставить PureConfig десериализоваться в JValue?
Обновление:
Я адаптировал ответ Gagandeep к моей старой версии PureConfig:
implicit val configReader: ConfigReader[JValue] = new ConfigReader[JValue] {
override def from(cur: ConfigCursor): Either[ConfigReaderFailures, JValue] =
cur.asString match {
case Right(jsonString: String) => Right(parse(jsonString))
case Left(configReaderFailures: ConfigReaderFailures) => Left(configReaderFailures)
}
}
Это изменило сообщение об ошибке, которое я считаю прогрессом:
Left(ConfigReaderFailures(ConvertFailure(WrongType(OBJECT,Set(STRING)),None,json),List()))
Кажется, PureConfig где-то ожидал String, но вместо этого обнаружил и Object. Я не уверен, где лежит разъединение. Я использую cur.asString
, чтобы гарантировать, что элемент возвращается как соответствующий тип.
Обновление 2:
Это, вероятно, не самое надежное решение, ноэто работает для моего теста:
implicit val configReader: ConfigReader[JValue] = new ConfigReader[JValue] {
override def from(cur: ConfigCursor): Either[ConfigReaderFailures, JValue] = {
Right(
// Parse PureConfig-rendered JSON.
parse(
// Render config as JSON.
cur.value.render(ConfigRenderOptions.concise.setJson(true))
)
)
}
}