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
- Host: GitHub
- URL: https://github.com/sunlulu427/autoconverter
- Owner: sunlulu427
- Created: 2023-12-28T12:58:20.000Z (almost 2 years ago)
- Default Branch: develop
- Last Pushed: 2024-10-31T14:09:48.000Z (12 months ago)
- Last Synced: 2025-03-28T08:11:49.790Z (7 months ago)
- Topics: json, kcp, kotlin-poet, ksp
- Language: Kotlin
- Homepage:
- Size: 163 KB
- Stars: 1
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
[](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