0

Due to a bug in my code I ended up serializing complex Map[String, AnyRef] objects using .toString when what I actually intended was JSON serialization. Now I have strings representing maps of arbitrary levels of nesting.

My goal is to transform these representations into JSON without losing any information or by losing the least amount of information possible.

What approach should I follow to accomplish this?

enzo
  • 193
  • 2
  • 14
  • 2
    Since this is only a temporary fix o recover some data. I would try to paste those string as a literal map in a Scala file and leave the scalac compiler to interpret them. – Luis Miguel Mejía Suárez Jan 15 '20 at 12:07
  • @LuisMiguelMejíaSuárez this is an interesting idea. The toString method doesn't output a string that can be parsed by the compiler. However, if I wrap every value in double quotes, then it might. This could work as a last resort method because it has the downside of automatically losing all type information. – enzo Jan 15 '20 at 12:12

1 Answers1

3

It really depends on what you have in these Strings. Problem is that .toString on its own looses some information:

@ Map("test" -> 1).toString
res1: String = "Map(test -> 1)"

@ Map("debug -> 2, test" -> 1).toString
res2: String = "Map(debug -> 2, test -> 1)"

@ Map("debug" -> 2, "test" -> 1).toString
res3: String = "Map(debug -> 2, test -> 1)"

How would you figure out if you have case from res2 or res3? In general if any of these Strings you used as keys contains , you will have some problematic case as there either will be ambiguities or syntax errors (if you attempt to parse things).

However, if you didn't have those you can:

  • remove initial Map( and final ) using .substring *.split the result using '","' as a separator
  • .map thw result to .split key from value, trim both sides
  • then the only issue would be parsing the values (AnyRefis not very specific).

Alternatively:

  • open Sublime Text (or any other editor with multiline edition support)
  • paste your code there
  • select -> and use it for multiline select in whole file
  • use ctrl+arrows to add " around key to make it parsable String
  • use the same method for adjusting AnyRefs if needed
  • copy code back into Scala and evaluate
Mateusz Kubuszok
  • 24,995
  • 4
  • 42
  • 64
  • In the end I decided to use Scala's [FastParse](http://www.lihaoyi.com/fastparse/#FastParse2.2.2) library to parse the strings. Although they are mostly sane, I preferred to use a more robust parsing mechanism to make sure the data is as correct as possible. The only data loss I incurred was in lists containing strings that may have commas in them. – enzo Jan 17 '20 at 12:00