Имам дълбоко вложени анализатори на JSON (използвайки json4s.jackson
), които се опитвам да опростя с помощта на класове case.
Проблемът ми е... някои от полетата започват с числа, но scala не може да има име на аргумент, което започва с цифров знак.
Пример:
import org.json4s.jackson.JsonMethods._
import org.json4s._
implicit val formats = DefaultFormats
val jsonStr = """{"5gLog":{"i":99}}""" // <--- note the field "5gLog"
val jval = parse(jsonStr)
case class Raw5gLog(i: Int)
val raw5gLog = (jval \ "5gLog").extract[Raw5gLog]
Това работи. Но това, което трябва да направя, тъй като тези полета са вложени дълбоко в JSON... е нещо подобно...
val jsonStr = """{"xgLog":{"i":99}}"""
val jval = parse(jsonStr)
case class RawRecord(xgLog: Raw5gLog)
val rawRecord = jval.extract[RawRecord]
Това би работило... ако полетата са именувани като xgLog
, но полетата всъщност са именувани като 5gLog
както по-горе, и не мога да дам име на аргумент на клас като 5gLog
...
case class RawRecord(5gLog: Raw5gLog)
// error: Invalid literal number
Мислех си за нещо подобно
parse(jsonStr.replace("\"5g", "\"fiveg"))
Но има реални данни, извън имената на полетата, в JSON, които могат да бъдат засегнати.
Най-доброто решение, което мога да измисля, е да добавя допълнителни методи за прилагане към засегнатите класове на случай...
case class RawRecord(fivegLog: Raw5gLog)
object RawRecord {
def apply(jval: JValue): RawRecord =
RawRecord( (jval \ "5gLog").extract[Raw5gLog] )
}
val rawRecord = RawRecord(jval)
Но имам чувството, че всеки път, когато направя някакво структурно различно решение като това за краен случай, това винаги е началото на кода ми, който се превръща в бъркотия. Бих могъл да дам на всеки клас case нов метод за прилагане и да го използвам за всичко, но изглежда като много допълнителен код за малка част от данните.
Има ли по-добър начин?