It would be really nice if there were a way to recreate a data class from the string it outputs.
My use case is an Android app that uses profiles, represented by a Profile data class. They’re persisted by storing the Profile.toString() in the Android shared preferences. Then when the app loads again, I need to reconstruct a Profile from the string. Right now I’m using json and overriding toString(), which works but requires me to hard-code the keys for each of the fields – not a very general solution.
If there’s a way to write this as an extension function, that would be awesome, but I don’t think there’s a way to get the name of a val/var without language support.
There are some tricky questions about how to parse.
Simplest case:
data class Place(val name: String)
val ambiguousString = "Place(name=park, title=field)"
val howShouldWeParseThis = Place.fromString(amgbiguousString)
val option1 = Place("park, title=field") // Longest possible
val option2 = Place("park") // Shortest possible
More complex
data class Person(val name: String, nickname: String)
val ambiguousString = "Person(name=I, nickname=we nickname=us)"
val howShouldWeParseThis = Person.fromString(ambiguousString)
val option1 = Person("I", "we, nickname=us") // First, longest possible declaration
val option2 = Person("I, nickname=we", "us") // Last, longest possible declaration
val option3 = Person("I", "we") // First, shortest possible declaration
val option4 = Person("I", "us") // Last, shortest possible declaration
Hard
data class Vacation(val person: Person, val place: Place)
// These both have obvious correct answers that are hard (impossible?) to parse
// using the same set of rules.
val closedParens = "Vacation(person=Person(name=me, nickname=place=Place(name=here)), place=Place(name=here))"
val openParen = "Vacation(person=Person(name=me, nickname=place=Place(name=here), place=Place(name=here))"
val correctClosed = Vacation(Person("me", "place=Place(name=here)"), Place("there"))
val correctOpen = Vacation(Person("me", "place=Place(name=here"), Place("there"))
Probably the most elegant solution would be, if you can’t perfectly parse the string, throw an exception, and the string contained in the exception is the best-effort parsing (probably, the first, shortest values, with invalid parts ignored). So, the caller can catch it (or not) and then decide for themselves whether to use it or throw it away.