AutoConverter is a simple tool to convert data classes to JSONObject. It can be used in Android log entity conversion, or in any other use case where you need to convert a data class to a JSONObject.
I planned two versions, one is the ksp version, and the other is kcp and IDE plugin version.
- serialization: toJSONObject
- deserialization: fromJSONObject, it is defined as a extended function for KClass
- nested classes
- naming strategy for properties, e.g. camel to underline
- code style config, e.g. indent
- fields marked nullable
- conversion config: JSONArray/List, JSONObject/Map
- kcp and idea plugin version
- publish to maven central
/**
* Auto convert annotation
* @property functions enabled auto convert functions, toJSONObject by default
* @property namingStrategy naming strategy, None by default
* @property filePostfix file postfix, Ext by default, filename is ClassName + filePostfix
* @constructor Create empty Auto convert
*/
@MustBeDocumented
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.BINARY)
annotation class AutoConvert(
val functions: Array<ACFunction> = [ACFunction.ToJSONObject],
val namingStrategy: NamingStrategy = NamingStrategy.None,
val filePostfix: String = "Ext"
)
package com.mato.stg4cpp
import com.mato.stg4.annotation.ACFunction
import com.mato.stg4.annotation.AutoConvert
import com.mato.stg4cpp.pkg2.Location
@AutoConvert(functions = [ACFunction.FromJSONObject, ACFunction.ToJSONObject])
data class Restaurant(
val score: Float,
val comments: Int = 0,
val location: Location? = null,
val foods: List<String> = emptyList(),
)
// Location.kt, it's a nested class, too. And it has different package name with the outer.
package com.mato.stg4cpp.pkg2
import com.mato.stg4.annotation.ACFunction
import com.mato.stg4.annotation.AutoConvert
@AutoConvert(functions = [ACFunction.ToJSONObject, ACFunction.FromJSONObject])
data class Location(
val longitude: Double = 0.0,
val latitude: Double = 0.0,
val address: String = ""
)
LocationExt.kt
// Read-only, generated by AutoConverter.
package com.mato.stg4cpp.pkg2
import kotlin.Result
import kotlin.reflect.KClass
import org.json.JSONObject
public fun Location.toJSONObject(): Result<JSONObject> = kotlin.runCatching {
JSONObject().also {
it.put("longitude", this.longitude)
it.put("latitude", this.latitude)
it.put("address", this.address)
}
}
public fun KClass<Location>.fromJSONObject(payload: JSONObject): Result<Location> =
kotlin.runCatching {
Location(
longitude = payload.get("longitude") as Double,
latitude = payload.get("latitude") as Double,
address = payload.get("address") as String
)
}
}
RestaurantExt.kt
// Read-only, generated by AutoConverter.
package com.mato.stg4cpp
import com.mato.stg4cpp.pkg2.Location
import com.mato.stg4cpp.pkg2.fromJSONObject
import com.mato.stg4cpp.pkg2.toJSONObject
import kotlin.Result
import kotlin.reflect.KClass
import org.json.JSONObject
public fun KClass<Restaurant>.fromJSONObject(payload: JSONObject): Result<Restaurant> =
kotlin.runCatching {
Restaurant(
score = payload.get("score") as Float,
comments = payload.get("comments") as Int,
location = payload.optJSONObject("location")?.let {
Location::class.fromJSONObject(it).getOrThrow() },
foods=payload.get("foods") as List<String>
)
}
public fun Restaurant.toJSONObject(): Result<JSONObject> = kotlin.runCatching {
JSONObject().also {
it.put("score", this.score)
it.put("comments", this.comments)
it.put("location", this.location?.toJSONObject()?.getOrThrow())
it.put("foods", this.foods)
}
}