An open API service indexing awesome lists of open source software.

https://github.com/sunlulu427/autoconverter

auto conversion between json and data class
https://github.com/sunlulu427/autoconverter

json kcp kotlin-poet ksp

Last synced: 6 months ago
JSON representation

auto conversion between json and data class

Awesome Lists containing this project

README

          

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
# AutoConverter

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.

- [x] serialization: toJSONObject
- [x] deserialization: fromJSONObject, it is defined as a extended function for KClass
- [x] nested classes
- [x] naming strategy for properties, e.g. camel to underline
- [x] code style config, e.g. indent
- [x] fields marked nullable
- [ ] conversion config: JSONArray/List, JSONObject/Map
- [ ] kcp and idea plugin version
- [ ] publish to maven central

## KSP

### Usage

#### The `AutoConvert` definition
```kotlin
/**
* 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.ToJSONObject],
val namingStrategy: NamingStrategy = NamingStrategy.None,
val filePostfix: String = "Ext"
)
```

#### Add `AutoConvert` to your classes
```kotlin
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 = emptyList(),
)
```
```kotlin
// 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 = ""
)
```

#### The generate files:
- `LocationExt.kt`
```kotlin
// 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 = kotlin.runCatching {
JSONObject().also {
it.put("longitude", this.longitude)
it.put("latitude", this.latitude)
it.put("address", this.address)
}
}

public fun KClass.fromJSONObject(payload: JSONObject): Result =
kotlin.runCatching {
Location(
longitude = payload.get("longitude") as Double,
latitude = payload.get("latitude") as Double,
address = payload.get("address") as String
)
}
}
```
- `RestaurantExt.kt`
```kotlin
// 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.fromJSONObject(payload: JSONObject): Result =
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
)
}

public fun Restaurant.toJSONObject(): Result = 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)
}
}
```

## [WIP] KCP