jsonkotlinklaxon

Adding static and instance methods to List in Kotlin


I'm trying to add Kotlin support to quicktype so that Kotlin developers can easy generate types and marshaling code in Kotlin from JSON.

For any given JSON sample, I want to generate a type T with a T.fromJson static method and a T.toJson instance method, but I am stuck when the top-level type is not an object. For example, given the JSON

[
  { "name": "David" }
]

quicktype sample.json -t People -l kotlin produces:

// To parse the JSON, add this file to your project and do:
//
//   val people = People.fromJson(jsonString)

import com.beust.klaxon.*

private val klaxon =
    Klaxon()

typealias People = List<Person>

data class Person (
    val name: String
) {
    public fun toJson() = klaxon.toJsonString(this as Any)

    companion object {
        public fun fromJson(json: String) = klaxon.parse<Person>(json)
    }
}

What I need to do now is figure out how to add the fromJson and toJson methods to the People type. Here was my first attempt:

open class People {
    public fun toJson() = klaxon.toJsonString(this as Any)

    companion object {
        public fun fromJson(json: String) = klaxon.parseArray<Person>(json)
    }
}

But I could not write open class People so I removed the alias:

open class List<Person> {
    public fun toJson() = klaxon.toJsonString(this as Any)

    companion object {
        public fun fromJson(json: String) = klaxon.parseArray<Person>(json)
    }
}

But now people.toJson() does not compile because the compiler cannot find the method.

Can I accomplish the semantics I want in Kotlin?


Solution

  • You can use

    class People : List<Person>()
    

    However personally I would simplify with the following generic top-level functions:

    fun <T> T.toJson() = Klaxon().toJsonString(this as Any)
    fun <T> fromJson(json: String) = Klaxon().parse<T>(json)
    fun <T> fromJsonArray(json: String) = Klaxon().parseArray<T>(json)