[kotlin][client] add support for unknown default case with Kotlinx Serialization (#12930)

* [kotlin][client] Kotlinx Serialization cleanup

* [kotlin][client] Kotlinx Serialization cleanup

* [kotlin][client] add support for unknown default case with Kotlinx Serialization

* [kotlin][client] add support for unknown default case with Kotlinx Serialization

* [kotlin][client] add support for unknown default case with Kotlinx Serialization

* [kotlin][client] improve Kotlinx Serialization naming

* [kotlin][client] improve Kotlinx Serialization naming
This commit is contained in:
Bruno Coelho 2022-07-26 09:42:19 +01:00 committed by GitHub
parent bc98014146
commit 87dc75780a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
62 changed files with 825 additions and 277 deletions

View File

@ -7,3 +7,5 @@ additionalProperties:
artifactId: kotlin-petstore-json-request-string artifactId: kotlin-petstore-json-request-string
parcelizeModels: true parcelizeModels: true
supportAndroidApiLevel25AndBelow: true supportAndroidApiLevel25AndBelow: true
serializationLibrary: kotlinx_serialization
enumUnknownDefaultCase: "true"

View File

@ -5,3 +5,5 @@ templateDir: modules/openapi-generator/src/main/resources/kotlin-client
additionalProperties: additionalProperties:
artifactId: kotlin-uppercase-enum artifactId: kotlin-uppercase-enum
enumPropertyNaming: UPPERCASE enumPropertyNaming: UPPERCASE
serializationLibrary: kotlinx_serialization
enumUnknownDefaultCase: "true"

View File

@ -19,6 +19,13 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo
import {{#serializableModel}}kotlinx.serialization.Serializable as KSerializable{{/serializableModel}}{{^serializableModel}}kotlinx.serialization.Serializable{{/serializableModel}} import {{#serializableModel}}kotlinx.serialization.Serializable as KSerializable{{/serializableModel}}{{^serializableModel}}kotlinx.serialization.Serializable{{/serializableModel}}
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Contextual import kotlinx.serialization.Contextual
{{#enumUnknownDefaultCase}}
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
{{/enumUnknownDefaultCase}}
{{#hasEnums}} {{#hasEnums}}
{{/hasEnums}} {{/hasEnums}}
{{/kotlinx_serialization}} {{/kotlinx_serialization}}
@ -88,7 +95,7 @@ import {{packageName}}.infrastructure.ITransformForStorage
*/ */
{{^multiplatform}} {{^multiplatform}}
{{#kotlinx_serialization}} {{#kotlinx_serialization}}
{{#serializableModel}}@KSerializable{{/serializableModel}}{{^serializableModel}}@Serializable{{/serializableModel}} {{#serializableModel}}@KSerializable{{/serializableModel}}{{^serializableModel}}@Serializable{{#enumUnknownDefaultCase}}(with = {{classname}}Serializer::class){{/enumUnknownDefaultCase}}{{/serializableModel}}
{{/kotlinx_serialization}} {{/kotlinx_serialization}}
{{/multiplatform}} {{/multiplatform}}
{{#multiplatform}} {{#multiplatform}}
@ -116,7 +123,22 @@ import {{packageName}}.infrastructure.ITransformForStorage
{{/multiplatform}} {{/multiplatform}}
{{/enumVars}} {{/enumVars}}
{{/allowableValues}} {{/allowableValues}}
}{{#kotlinx_serialization}}{{#enumUnknownDefaultCase}}
@Serializer(forClass = {{{nameInCamelCase}}}::class)
internal object {{nameInCamelCase}}Serializer : KSerializer<{{nameInCamelCase}}> {
override val descriptor = {{{dataType}}}.serializer().descriptor
override fun deserialize(decoder: Decoder): {{nameInCamelCase}} {
val value = decoder.decodeSerializableValue({{{dataType}}}.serializer())
return {{nameInCamelCase}}.values().firstOrNull { it.value == value }
?: {{nameInCamelCase}}.{{#allowableValues}}{{#enumVars}}{{#-last}}{{&name}}{{/-last}}{{/enumVars}}{{/allowableValues}}
} }
override fun serialize(encoder: Encoder, value: {{nameInCamelCase}}) {
encoder.encodeSerializableValue({{{dataType}}}.serializer(), value.value)
}
}{{/enumUnknownDefaultCase}}{{/kotlinx_serialization}}
{{/isEnum}} {{/isEnum}}
{{/vars}} {{/vars}}
{{/hasEnums}} {{/hasEnums}}

View File

@ -11,6 +11,13 @@ import com.fasterxml.jackson.annotation.JsonProperty
{{#kotlinx_serialization}} {{#kotlinx_serialization}}
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
{{#enumUnknownDefaultCase}}
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
{{/enumUnknownDefaultCase}}
{{/kotlinx_serialization}} {{/kotlinx_serialization}}
{{/multiplatform}} {{/multiplatform}}
{{#multiplatform}} {{#multiplatform}}
@ -22,7 +29,7 @@ import kotlinx.serialization.*
* *
* Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}},{{/-last}}{{/enumVars}}{{/allowableValues}} * Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}},{{/-last}}{{/enumVars}}{{/allowableValues}}
*/ */
{{#multiplatform}}@Serializable{{/multiplatform}}{{#kotlinx_serialization}}@Serializable{{/kotlinx_serialization}} {{#multiplatform}}@Serializable{{/multiplatform}}{{#kotlinx_serialization}}@Serializable{{#enumUnknownDefaultCase}}(with = {{classname}}Serializer::class){{/enumUnknownDefaultCase}}{{/kotlinx_serialization}}
{{#nonPublicApi}}internal {{/nonPublicApi}}enum class {{classname}}(val value: {{{dataType}}}) { {{#nonPublicApi}}internal {{/nonPublicApi}}enum class {{classname}}(val value: {{{dataType}}}) {
{{#allowableValues}}{{#enumVars}} {{#allowableValues}}{{#enumVars}}
{{^multiplatform}} {{^multiplatform}}
@ -79,4 +86,19 @@ import kotlinx.serialization.*
} }
} }
} }
} }{{#kotlinx_serialization}}{{#enumUnknownDefaultCase}}
@Serializer(forClass = {{classname}}::class)
internal object {{classname}}Serializer : KSerializer<{{classname}}> {
override val descriptor = {{{dataType}}}.serializer().descriptor
override fun deserialize(decoder: Decoder): {{classname}} {
val value = decoder.decodeSerializableValue({{{dataType}}}.serializer())
return {{classname}}.values().firstOrNull { it.value == value }
?: {{classname}}.{{#allowableValues}}{{#enumVars}}{{#-last}}{{&name}}{{/-last}}{{/enumVars}}{{/allowableValues}}
}
override fun serialize(encoder: Encoder, value: {{classname}}) {
encoder.encodeSerializableValue({{{dataType}}}.serializer(), value.value)
}
}{{/enumUnknownDefaultCase}}{{/kotlinx_serialization}}

View File

@ -72,7 +72,7 @@ import org.threeten.bp.format.DateTimeFormatter
{{/gson}} {{/gson}}
{{#kotlinx_serialization}} {{#kotlinx_serialization}}
@Serializer(forClass = LocalDate::class) @Serializer(forClass = LocalDate::class)
object LocalDateAdapter : KSerializer<LocalDate> { {{#nonPublicApi}}internal {{/nonPublicApi}}object LocalDateAdapter : KSerializer<LocalDate> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalDate", PrimitiveKind.STRING) override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalDate", PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: LocalDate) { override fun serialize(encoder: Encoder, value: LocalDate) {

View File

@ -72,7 +72,7 @@ import org.threeten.bp.format.DateTimeFormatter
{{/gson}} {{/gson}}
{{#kotlinx_serialization}} {{#kotlinx_serialization}}
@Serializer(forClass = LocalDateTime::class) @Serializer(forClass = LocalDateTime::class)
object LocalDateTimeAdapter : KSerializer<LocalDateTime> { {{#nonPublicApi}}internal {{/nonPublicApi}}object LocalDateTimeAdapter : KSerializer<LocalDateTime> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalDateTime", PrimitiveKind.STRING) override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalDateTime", PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: LocalDateTime) { override fun serialize(encoder: Encoder, value: LocalDateTime) {

View File

@ -72,7 +72,7 @@ import org.threeten.bp.format.DateTimeFormatter
{{/gson}} {{/gson}}
{{#kotlinx_serialization}} {{#kotlinx_serialization}}
@Serializer(forClass = OffsetDateTime::class) @Serializer(forClass = OffsetDateTime::class)
object OffsetDateTimeAdapter : KSerializer<OffsetDateTime> { {{#nonPublicApi}}internal {{/nonPublicApi}}object OffsetDateTimeAdapter : KSerializer<OffsetDateTime> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("OffsetDateTime", PrimitiveKind.STRING) override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("OffsetDateTime", PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: OffsetDateTime) { override fun serialize(encoder: Encoder, value: OffsetDateTime) {

View File

@ -98,8 +98,13 @@ import java.util.concurrent.atomic.AtomicLong
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
{{/jackson}} {{/jackson}}
{{#kotlinx_serialization}} {{#kotlinx_serialization}}
@Deprecated("Use Serializer.kotlinxSerializationAdapters instead", replaceWith = ReplaceWith("Serializer.kotlinxSerializationAdapters"))
@JvmStatic @JvmStatic
val kotlinSerializationAdapters = SerializersModule { val kotlinSerializationAdapters: SerializersModule
get() { return kotlinxSerializationAdapters }
@JvmStatic
val kotlinxSerializationAdapters = SerializersModule {
contextual(BigDecimal::class, BigDecimalAdapter) contextual(BigDecimal::class, BigDecimalAdapter)
contextual(BigInteger::class, BigIntegerAdapter) contextual(BigInteger::class, BigIntegerAdapter)
contextual(LocalDate::class, LocalDateAdapter) contextual(LocalDate::class, LocalDateAdapter)
@ -114,7 +119,18 @@ import java.util.concurrent.atomic.AtomicLong
contextual(StringBuilder::class, StringBuilderAdapter) contextual(StringBuilder::class, StringBuilderAdapter)
} }
@Deprecated("Use Serializer.kotlinxSerializationJson instead", replaceWith = ReplaceWith("Serializer.kotlinxSerializationJson"))
@JvmStatic @JvmStatic
val jvmJson: Json by lazy { Json { serializersModule = kotlinSerializationAdapters } } val jvmJson: Json
get() { return kotlinxSerializationJson }
@JvmStatic
val kotlinxSerializationJson: Json by lazy {
Json {
serializersModule = kotlinxSerializationAdapters
ignoreUnknownKeys = true
isLenient = true
}
}
{{/kotlinx_serialization}} {{/kotlinx_serialization}}
} }

View File

@ -26,7 +26,7 @@ import java.net.URI
{{/moshi}} {{/moshi}}
{{#kotlinx_serialization}} {{#kotlinx_serialization}}
@Serializer(forClass = URI::class) @Serializer(forClass = URI::class)
object URIAdapter : KSerializer<URI> { {{#nonPublicApi}}internal {{/nonPublicApi}}object URIAdapter : KSerializer<URI> {
override fun serialize(encoder: Encoder, value: URI) { override fun serialize(encoder: Encoder, value: URI) {
encoder.encodeString(value.toASCIIString()) encoder.encodeString(value.toASCIIString())
} }

View File

@ -26,7 +26,7 @@ import java.util.UUID
{{/moshi}} {{/moshi}}
{{#kotlinx_serialization}} {{#kotlinx_serialization}}
@Serializer(forClass = UUID::class) @Serializer(forClass = UUID::class)
object UUIDAdapter : KSerializer<UUID> { {{#nonPublicApi}}internal {{/nonPublicApi}}object UUIDAdapter : KSerializer<UUID> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("UUID", PrimitiveKind.STRING) override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("UUID", PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: UUID) { override fun serialize(encoder: Encoder, value: UUID) {

View File

@ -169,7 +169,7 @@ import com.squareup.moshi.adapter
MediaType.parse(mediaType ?: JsonMediaType), Serializer.jacksonObjectMapper.writeValueAsString(content) MediaType.parse(mediaType ?: JsonMediaType), Serializer.jacksonObjectMapper.writeValueAsString(content)
{{/jackson}} {{/jackson}}
{{#kotlinx_serialization}} {{#kotlinx_serialization}}
MediaType.parse(mediaType ?: JsonMediaType), Serializer.jvmJson.encodeToString(content) MediaType.parse(mediaType ?: JsonMediaType), Serializer.kotlinxSerializationJson.encodeToString(content)
{{/kotlinx_serialization}} {{/kotlinx_serialization}}
) )
} }
@ -188,7 +188,7 @@ import com.squareup.moshi.adapter
Serializer.jacksonObjectMapper.writeValueAsString(content) Serializer.jacksonObjectMapper.writeValueAsString(content)
{{/jackson}} {{/jackson}}
{{#kotlinx_serialization}} {{#kotlinx_serialization}}
Serializer.jvmJson.encodeToString(content) Serializer.kotlinxSerializationJson.encodeToString(content)
{{/kotlinx_serialization}} {{/kotlinx_serialization}}
.toRequestBody((mediaType ?: JsonMediaType).toMediaTypeOrNull()) .toRequestBody((mediaType ?: JsonMediaType).toMediaTypeOrNull())
} }
@ -236,7 +236,7 @@ import com.squareup.moshi.adapter
{{#moshi}}Serializer.moshi.adapter<T>().fromJson(bodyContent){{/moshi}}{{! {{#moshi}}Serializer.moshi.adapter<T>().fromJson(bodyContent){{/moshi}}{{!
}}{{#gson}}Serializer.gson.fromJson(bodyContent, (object: TypeToken<T>(){}).getType()){{/gson}}{{! }}{{#gson}}Serializer.gson.fromJson(bodyContent, (object: TypeToken<T>(){}).getType()){{/gson}}{{!
}}{{#jackson}}Serializer.jacksonObjectMapper.readValue(bodyContent, object: TypeReference<T>() {}){{/jackson}}{{! }}{{#jackson}}Serializer.jacksonObjectMapper.readValue(bodyContent, object: TypeReference<T>() {}){{/jackson}}{{!
}}{{#kotlinx_serialization}}Serializer.jvmJson.decodeFromString<T>(bodyContent){{/kotlinx_serialization}} }}{{#kotlinx_serialization}}Serializer.kotlinxSerializationJson.decodeFromString<T>(bodyContent){{/kotlinx_serialization}}
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body.") else -> throw UnsupportedOperationException("responseBody currently only supports JSON body.")
} }
} }
@ -432,7 +432,7 @@ import com.squareup.moshi.adapter
return Serializer.jacksonObjectMapper.writeValueAsString(value).replace("\"", "") return Serializer.jacksonObjectMapper.writeValueAsString(value).replace("\"", "")
{{/jackson}} {{/jackson}}
{{#kotlinx_serialization}} {{#kotlinx_serialization}}
return Serializer.jvmJson.encodeToString(value).replace("\"", "") return Serializer.kotlinxSerializationJson.encodeToString(value).replace("\"", "")
{{/kotlinx_serialization}} {{/kotlinx_serialization}}
{{/toJson}} {{/toJson}}
{{^toJson}} {{^toJson}}

View File

@ -51,7 +51,7 @@ import retrofit2.converter.moshi.MoshiConverterFactory
{{#kotlinx_serialization}} {{#kotlinx_serialization}}
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import {{packageName}}.infrastructure.Serializer.jvmJson import {{packageName}}.infrastructure.Serializer.kotlinxSerializationJson
import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaType
{{/kotlinx_serialization}} {{/kotlinx_serialization}}
@ -84,7 +84,7 @@ import okhttp3.MediaType.Companion.toMediaType
.addConverterFactory(MoshiConverterFactory.create(serializerBuilder.build())) .addConverterFactory(MoshiConverterFactory.create(serializerBuilder.build()))
{{/moshi}} {{/moshi}}
{{#kotlinx_serialization}} {{#kotlinx_serialization}}
.addConverterFactory(jvmJson.asConverterFactory("application/json".toMediaType())) .addConverterFactory(kotlinxSerializationJson.asConverterFactory("application/json".toMediaType()))
{{/kotlinx_serialization}} {{/kotlinx_serialization}}
.apply { .apply {
if (converterFactory != null) { if (converterFactory != null) {

View File

@ -13,6 +13,7 @@ gradle/wrapper/gradle-wrapper.jar
gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.properties
gradlew gradlew
gradlew.bat gradlew.bat
proguard-rules.pro
settings.gradle settings.gradle
src/main/kotlin/org/openapitools/client/apis/PetApi.kt src/main/kotlin/org/openapitools/client/apis/PetApi.kt
src/main/kotlin/org/openapitools/client/apis/StoreApi.kt src/main/kotlin/org/openapitools/client/apis/StoreApi.kt
@ -20,9 +21,11 @@ src/main/kotlin/org/openapitools/client/apis/UserApi.kt
src/main/kotlin/org/openapitools/client/infrastructure/ApiAbstractions.kt src/main/kotlin/org/openapitools/client/infrastructure/ApiAbstractions.kt
src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
src/main/kotlin/org/openapitools/client/infrastructure/ApiResponse.kt src/main/kotlin/org/openapitools/client/infrastructure/ApiResponse.kt
src/main/kotlin/org/openapitools/client/infrastructure/AtomicBooleanAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/AtomicIntegerAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/AtomicLongAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/BigDecimalAdapter.kt src/main/kotlin/org/openapitools/client/infrastructure/BigDecimalAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/BigIntegerAdapter.kt src/main/kotlin/org/openapitools/client/infrastructure/BigIntegerAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/ByteArrayAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/Errors.kt src/main/kotlin/org/openapitools/client/infrastructure/Errors.kt
src/main/kotlin/org/openapitools/client/infrastructure/LocalDateAdapter.kt src/main/kotlin/org/openapitools/client/infrastructure/LocalDateAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/LocalDateTimeAdapter.kt src/main/kotlin/org/openapitools/client/infrastructure/LocalDateTimeAdapter.kt
@ -32,7 +35,9 @@ src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt
src/main/kotlin/org/openapitools/client/infrastructure/RequestMethod.kt src/main/kotlin/org/openapitools/client/infrastructure/RequestMethod.kt
src/main/kotlin/org/openapitools/client/infrastructure/ResponseExtensions.kt src/main/kotlin/org/openapitools/client/infrastructure/ResponseExtensions.kt
src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt
src/main/kotlin/org/openapitools/client/infrastructure/StringBuilderAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/URIAdapter.kt src/main/kotlin/org/openapitools/client/infrastructure/URIAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/URLAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/UUIDAdapter.kt src/main/kotlin/org/openapitools/client/infrastructure/UUIDAdapter.kt
src/main/kotlin/org/openapitools/client/models/Category.kt src/main/kotlin/org/openapitools/client/models/Category.kt
src/main/kotlin/org/openapitools/client/models/ModelApiResponse.kt src/main/kotlin/org/openapitools/client/models/ModelApiResponse.kt

View File

@ -14,11 +14,13 @@ buildscript {
} }
dependencies { dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
} }
} }
apply plugin: 'kotlin' apply plugin: 'kotlin'
apply plugin: 'kotlin-parcelize' apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlinx-serialization'
repositories { repositories {
maven { url "https://repo1.maven.org/maven2" } maven { url "https://repo1.maven.org/maven2" }
@ -30,9 +32,13 @@ test {
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.1"
implementation "com.squareup.moshi:moshi-kotlin:1.12.0"
implementation "com.squareup.moshi:moshi-adapters:1.12.0"
implementation "com.squareup.okhttp3:okhttp:4.9.1" implementation "com.squareup.okhttp3:okhttp:4.9.1"
testImplementation "io.kotlintest:kotlintest-runner-junit5:3.4.2" testImplementation "io.kotlintest:kotlintest-runner-junit5:3.4.2"
} }
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
kotlinOptions {
freeCompilerArgs += "-Xopt-in=kotlinx.serialization.ExperimentalSerializationApi"
}
}

View File

@ -0,0 +1,11 @@
-keepattributes *Annotation*, InnerClasses
-dontnote kotlinx.serialization.AnnotationsKt # core serialization annotations
# kotlinx-serialization-json specific. Add this if you have java.lang.NoClassDefFoundError kotlinx.serialization.json.JsonObjectSerializer
-keepclassmembers class kotlinx.serialization.json.** { *** Companion; }
-keepclasseswithmembers class kotlinx.serialization.json.** { kotlinx.serialization.KSerializer serializer(...); }
# project specific.
-keep,includedescriptorclasses class org.openapitools.client.models.**$$serializer { *; }
-keepclassmembers class org.openapitools.client.models.** { *** Companion; }
-keepclasseswithmembers class org.openapitools.client.models.** { kotlinx.serialization.KSerializer serializer(...); }

View File

@ -26,7 +26,8 @@ import okhttp3.OkHttpClient
import org.openapitools.client.models.ModelApiResponse import org.openapitools.client.models.ModelApiResponse
import org.openapitools.client.models.Pet import org.openapitools.client.models.Pet
import com.squareup.moshi.Json import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import org.openapitools.client.infrastructure.ApiClient import org.openapitools.client.infrastructure.ApiClient
import org.openapitools.client.infrastructure.ApiResponse import org.openapitools.client.infrastructure.ApiResponse

View File

@ -25,7 +25,8 @@ import okhttp3.OkHttpClient
import org.openapitools.client.models.Order import org.openapitools.client.models.Order
import com.squareup.moshi.Json import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import org.openapitools.client.infrastructure.ApiClient import org.openapitools.client.infrastructure.ApiClient
import org.openapitools.client.infrastructure.ApiResponse import org.openapitools.client.infrastructure.ApiResponse

View File

@ -25,7 +25,8 @@ import okhttp3.OkHttpClient
import org.openapitools.client.models.User import org.openapitools.client.models.User
import com.squareup.moshi.Json import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import org.openapitools.client.infrastructure.ApiClient import org.openapitools.client.infrastructure.ApiClient
import org.openapitools.client.infrastructure.ApiResponse import org.openapitools.client.infrastructure.ApiResponse

View File

@ -28,7 +28,8 @@ import java.time.LocalTime
import java.time.OffsetDateTime import java.time.OffsetDateTime
import java.time.OffsetTime import java.time.OffsetTime
import java.util.Locale import java.util.Locale
import com.squareup.moshi.adapter import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
open class ApiClient(val baseUrl: String, val client: OkHttpClient = defaultClient) { open class ApiClient(val baseUrl: String, val client: OkHttpClient = defaultClient) {
companion object { companion object {
@ -105,7 +106,7 @@ open class ApiClient(val baseUrl: String, val client: OkHttpClient = defaultClie
if (content == null) { if (content == null) {
EMPTY_REQUEST EMPTY_REQUEST
} else { } else {
Serializer.moshi.adapter(T::class.java).toJson(content) Serializer.kotlinxSerializationJson.encodeToString(content)
.toRequestBody((mediaType ?: JsonMediaType).toMediaTypeOrNull()) .toRequestBody((mediaType ?: JsonMediaType).toMediaTypeOrNull())
} }
mediaType == XmlMediaType -> throw UnsupportedOperationException("xml not currently supported.") mediaType == XmlMediaType -> throw UnsupportedOperationException("xml not currently supported.")
@ -113,7 +114,6 @@ open class ApiClient(val baseUrl: String, val client: OkHttpClient = defaultClie
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body and File body.") else -> throw UnsupportedOperationException("requestBody currently only supports JSON body and File body.")
} }
@OptIn(ExperimentalStdlibApi::class)
protected inline fun <reified T: Any?> responseBody(body: ResponseBody?, mediaType: String? = JsonMediaType): T? { protected inline fun <reified T: Any?> responseBody(body: ResponseBody?, mediaType: String? = JsonMediaType): T? {
if(body == null) { if(body == null) {
return null return null
@ -140,7 +140,7 @@ open class ApiClient(val baseUrl: String, val client: OkHttpClient = defaultClie
} }
return when { return when {
mediaType==null || (mediaType.startsWith("application/") && mediaType.endsWith("json")) -> mediaType==null || (mediaType.startsWith("application/") && mediaType.endsWith("json")) ->
Serializer.moshi.adapter<T>().fromJson(bodyContent) Serializer.kotlinxSerializationJson.decodeFromString<T>(bodyContent)
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body.") else -> throw UnsupportedOperationException("responseBody currently only supports JSON body.")
} }
} }

View File

@ -0,0 +1,21 @@
package org.openapitools.client.infrastructure
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.util.concurrent.atomic.AtomicBoolean
@Serializer(forClass = AtomicBoolean::class)
object AtomicBooleanAdapter : KSerializer<AtomicBoolean> {
override fun serialize(encoder: Encoder, value: AtomicBoolean) {
encoder.encodeBoolean(value.get())
}
override fun deserialize(decoder: Decoder): AtomicBoolean = AtomicBoolean(decoder.decodeBoolean())
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("AtomicBoolean", PrimitiveKind.BOOLEAN)
}

View File

@ -0,0 +1,21 @@
package org.openapitools.client.infrastructure
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.util.concurrent.atomic.AtomicInteger
@Serializer(forClass = AtomicInteger::class)
object AtomicIntegerAdapter : KSerializer<AtomicInteger> {
override fun serialize(encoder: Encoder, value: AtomicInteger) {
encoder.encodeInt(value.get())
}
override fun deserialize(decoder: Decoder): AtomicInteger = AtomicInteger(decoder.decodeInt())
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("AtomicInteger", PrimitiveKind.INT)
}

View File

@ -0,0 +1,21 @@
package org.openapitools.client.infrastructure
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.util.concurrent.atomic.AtomicLong
@Serializer(forClass = AtomicLong::class)
object AtomicLongAdapter : KSerializer<AtomicLong> {
override fun serialize(encoder: Encoder, value: AtomicLong) {
encoder.encodeLong(value.get())
}
override fun deserialize(decoder: Decoder): AtomicLong = AtomicLong(decoder.decodeLong())
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("AtomicLong", PrimitiveKind.LONG)
}

View File

@ -1,17 +1,17 @@
package org.openapitools.client.infrastructure package org.openapitools.client.infrastructure
import com.squareup.moshi.FromJson import kotlinx.serialization.KSerializer
import com.squareup.moshi.ToJson import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.math.BigDecimal import java.math.BigDecimal
class BigDecimalAdapter { @Serializer(forClass = BigDecimal::class)
@ToJson object BigDecimalAdapter : KSerializer<BigDecimal> {
fun toJson(value: BigDecimal): String { override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("BigDecimal", PrimitiveKind.STRING)
return value.toPlainString() override fun deserialize(decoder: Decoder): BigDecimal = BigDecimal(decoder.decodeString())
} override fun serialize(encoder: Encoder, value: BigDecimal) = encoder.encodeString(value.toPlainString())
@FromJson
fun fromJson(value: String): BigDecimal {
return BigDecimal(value)
}
} }

View File

@ -1,17 +1,22 @@
package org.openapitools.client.infrastructure package org.openapitools.client.infrastructure
import com.squareup.moshi.FromJson import kotlinx.serialization.KSerializer
import com.squareup.moshi.ToJson import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.math.BigInteger import java.math.BigInteger
class BigIntegerAdapter { @Serializer(forClass = BigInteger::class)
@ToJson object BigIntegerAdapter : KSerializer<BigInteger> {
fun toJson(value: BigInteger): String { override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("BigInteger", PrimitiveKind.STRING)
return value.toString() override fun deserialize(decoder: Decoder): BigInteger {
return BigInteger(decoder.decodeString())
} }
@FromJson override fun serialize(encoder: Encoder, value: BigInteger) {
fun fromJson(value: String): BigInteger { encoder.encodeString(value.toString())
return BigInteger(value)
} }
} }

View File

@ -1,12 +0,0 @@
package org.openapitools.client.infrastructure
import com.squareup.moshi.FromJson
import com.squareup.moshi.ToJson
class ByteArrayAdapter {
@ToJson
fun toJson(data: ByteArray): String = String(data)
@FromJson
fun fromJson(data: String): ByteArray = data.toByteArray()
}

View File

@ -1,19 +1,24 @@
package org.openapitools.client.infrastructure package org.openapitools.client.infrastructure
import com.squareup.moshi.FromJson import kotlinx.serialization.KSerializer
import com.squareup.moshi.ToJson import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.time.LocalDate import java.time.LocalDate
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
class LocalDateAdapter { @Serializer(forClass = LocalDate::class)
@ToJson object LocalDateAdapter : KSerializer<LocalDate> {
fun toJson(value: LocalDate): String { override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalDate", PrimitiveKind.STRING)
return DateTimeFormatter.ISO_LOCAL_DATE.format(value)
override fun serialize(encoder: Encoder, value: LocalDate) {
encoder.encodeString(DateTimeFormatter.ISO_LOCAL_DATE.format(value))
} }
@FromJson override fun deserialize(decoder: Decoder): LocalDate {
fun fromJson(value: String): LocalDate { return LocalDate.parse(decoder.decodeString(), DateTimeFormatter.ISO_LOCAL_DATE)
return LocalDate.parse(value, DateTimeFormatter.ISO_LOCAL_DATE)
} }
} }

View File

@ -1,19 +1,24 @@
package org.openapitools.client.infrastructure package org.openapitools.client.infrastructure
import com.squareup.moshi.FromJson import kotlinx.serialization.KSerializer
import com.squareup.moshi.ToJson import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
class LocalDateTimeAdapter { @Serializer(forClass = LocalDateTime::class)
@ToJson object LocalDateTimeAdapter : KSerializer<LocalDateTime> {
fun toJson(value: LocalDateTime): String { override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalDateTime", PrimitiveKind.STRING)
return DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(value)
override fun serialize(encoder: Encoder, value: LocalDateTime) {
encoder.encodeString(DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(value))
} }
@FromJson override fun deserialize(decoder: Decoder): LocalDateTime {
fun fromJson(value: String): LocalDateTime { return LocalDateTime.parse(decoder.decodeString(), DateTimeFormatter.ISO_LOCAL_DATE_TIME)
return LocalDateTime.parse(value, DateTimeFormatter.ISO_LOCAL_DATE_TIME)
} }
} }

View File

@ -1,19 +1,24 @@
package org.openapitools.client.infrastructure package org.openapitools.client.infrastructure
import com.squareup.moshi.FromJson import kotlinx.serialization.KSerializer
import com.squareup.moshi.ToJson import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.time.OffsetDateTime import java.time.OffsetDateTime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
class OffsetDateTimeAdapter { @Serializer(forClass = OffsetDateTime::class)
@ToJson object OffsetDateTimeAdapter : KSerializer<OffsetDateTime> {
fun toJson(value: OffsetDateTime): String { override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("OffsetDateTime", PrimitiveKind.STRING)
return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(value)
override fun serialize(encoder: Encoder, value: OffsetDateTime) {
encoder.encodeString(DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(value))
} }
@FromJson override fun deserialize(decoder: Decoder): OffsetDateTime {
fun fromJson(value: String): OffsetDateTime { return OffsetDateTime.parse(decoder.decodeString(), DateTimeFormatter.ISO_OFFSET_DATE_TIME)
return OffsetDateTime.parse(value, DateTimeFormatter.ISO_OFFSET_DATE_TIME)
} }
} }

View File

@ -1,23 +1,52 @@
package org.openapitools.client.infrastructure package org.openapitools.client.infrastructure
import com.squareup.moshi.Moshi import java.math.BigDecimal
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory import java.math.BigInteger
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.OffsetDateTime
import java.util.UUID
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
import java.net.URI
import java.net.URL
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.atomic.AtomicLong
object Serializer { object Serializer {
@Deprecated("Use Serializer.kotlinxSerializationAdapters instead", replaceWith = ReplaceWith("Serializer.kotlinxSerializationAdapters"))
@JvmStatic @JvmStatic
val moshiBuilder: Moshi.Builder = Moshi.Builder() val kotlinSerializationAdapters: SerializersModule
.add(OffsetDateTimeAdapter()) get() { return kotlinxSerializationAdapters }
.add(LocalDateTimeAdapter())
.add(LocalDateAdapter())
.add(UUIDAdapter())
.add(ByteArrayAdapter())
.add(URIAdapter())
.add(KotlinJsonAdapterFactory())
.add(BigDecimalAdapter())
.add(BigIntegerAdapter())
@JvmStatic @JvmStatic
val moshi: Moshi by lazy { val kotlinxSerializationAdapters = SerializersModule {
moshiBuilder.build() contextual(BigDecimal::class, BigDecimalAdapter)
contextual(BigInteger::class, BigIntegerAdapter)
contextual(LocalDate::class, LocalDateAdapter)
contextual(LocalDateTime::class, LocalDateTimeAdapter)
contextual(OffsetDateTime::class, OffsetDateTimeAdapter)
contextual(UUID::class, UUIDAdapter)
contextual(AtomicInteger::class, AtomicIntegerAdapter)
contextual(AtomicLong::class, AtomicLongAdapter)
contextual(AtomicBoolean::class, AtomicBooleanAdapter)
contextual(URI::class, URIAdapter)
contextual(URL::class, URLAdapter)
contextual(StringBuilder::class, StringBuilderAdapter)
}
@Deprecated("Use Serializer.kotlinxSerializationJson instead", replaceWith = ReplaceWith("Serializer.kotlinxSerializationJson"))
@JvmStatic
val jvmJson: Json
get() { return kotlinxSerializationJson }
@JvmStatic
val kotlinxSerializationJson: Json by lazy {
Json {
serializersModule = kotlinxSerializationAdapters
ignoreUnknownKeys = true
isLenient = true
}
} }
} }

View File

@ -0,0 +1,20 @@
package org.openapitools.client.infrastructure
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
@Serializer(forClass = StringBuilder::class)
object StringBuilderAdapter : KSerializer<StringBuilder> {
override fun serialize(encoder: Encoder, value: StringBuilder) {
encoder.encodeString(value.toString())
}
override fun deserialize(decoder: Decoder): StringBuilder = StringBuilder(decoder.decodeString())
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("StringBuilder", PrimitiveKind.STRING)
}

View File

@ -1,13 +1,21 @@
package org.openapitools.client.infrastructure package org.openapitools.client.infrastructure
import com.squareup.moshi.FromJson import kotlinx.serialization.KSerializer
import com.squareup.moshi.ToJson import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.net.URI import java.net.URI
class URIAdapter { @Serializer(forClass = URI::class)
@ToJson object URIAdapter : KSerializer<URI> {
fun toJson(uri: URI) = uri.toString() override fun serialize(encoder: Encoder, value: URI) {
encoder.encodeString(value.toASCIIString())
}
@FromJson override fun deserialize(decoder: Decoder): URI = URI(decoder.decodeString())
fun fromJson(s: String): URI = URI.create(s)
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("URI", PrimitiveKind.STRING)
} }

View File

@ -0,0 +1,21 @@
package org.openapitools.client.infrastructure
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.net.URL
@Serializer(forClass = URL::class)
object URLAdapter : KSerializer<URL> {
override fun serialize(encoder: Encoder, value: URL) {
encoder.encodeString(value.toExternalForm())
}
override fun deserialize(decoder: Decoder): URL = URL(decoder.decodeString())
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("URL", PrimitiveKind.STRING)
}

View File

@ -1,13 +1,23 @@
package org.openapitools.client.infrastructure package org.openapitools.client.infrastructure
import com.squareup.moshi.FromJson import kotlinx.serialization.KSerializer
import com.squareup.moshi.ToJson import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.util.UUID import java.util.UUID
class UUIDAdapter { @Serializer(forClass = UUID::class)
@ToJson object UUIDAdapter : KSerializer<UUID> {
fun toJson(uuid: UUID) = uuid.toString() override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("UUID", PrimitiveKind.STRING)
@FromJson override fun serialize(encoder: Encoder, value: UUID) {
fun fromJson(s: String): UUID = UUID.fromString(s) encoder.encodeString(value.toString())
}
override fun deserialize(decoder: Decoder): UUID {
return UUID.fromString(decoder.decodeString())
}
} }

View File

@ -21,7 +21,14 @@
package org.openapitools.client.models package org.openapitools.client.models
import com.squareup.moshi.Json import kotlinx.serialization.Serializable
import kotlinx.serialization.SerialName
import kotlinx.serialization.Contextual
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import android.os.Parcelable import android.os.Parcelable
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ -32,13 +39,13 @@ import kotlinx.parcelize.Parcelize
* @param name * @param name
*/ */
@Parcelize @Parcelize
@Serializable
data class Category ( data class Category (
@Json(name = "id") @SerialName(value = "id")
val id: kotlin.Long? = null, val id: kotlin.Long? = null,
@Json(name = "name") @SerialName(value = "name")
val name: kotlin.String? = null val name: kotlin.String? = null
) : Parcelable ) : Parcelable

View File

@ -21,7 +21,14 @@
package org.openapitools.client.models package org.openapitools.client.models
import com.squareup.moshi.Json import kotlinx.serialization.Serializable
import kotlinx.serialization.SerialName
import kotlinx.serialization.Contextual
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import android.os.Parcelable import android.os.Parcelable
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ -33,16 +40,16 @@ import kotlinx.parcelize.Parcelize
* @param message * @param message
*/ */
@Parcelize @Parcelize
@Serializable
data class ModelApiResponse ( data class ModelApiResponse (
@Json(name = "code") @SerialName(value = "code")
val code: kotlin.Int? = null, val code: kotlin.Int? = null,
@Json(name = "type") @SerialName(value = "type")
val type: kotlin.String? = null, val type: kotlin.String? = null,
@Json(name = "message") @SerialName(value = "message")
val message: kotlin.String? = null val message: kotlin.String? = null
) : Parcelable ) : Parcelable

View File

@ -21,7 +21,14 @@
package org.openapitools.client.models package org.openapitools.client.models
import com.squareup.moshi.Json import kotlinx.serialization.Serializable
import kotlinx.serialization.SerialName
import kotlinx.serialization.Contextual
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import android.os.Parcelable import android.os.Parcelable
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ -36,26 +43,26 @@ import kotlinx.parcelize.Parcelize
* @param complete * @param complete
*/ */
@Parcelize @Parcelize
@Serializable
data class Order ( data class Order (
@Json(name = "id") @SerialName(value = "id")
val id: kotlin.Long? = null, val id: kotlin.Long? = null,
@Json(name = "petId") @SerialName(value = "petId")
val petId: kotlin.Long? = null, val petId: kotlin.Long? = null,
@Json(name = "quantity") @SerialName(value = "quantity")
val quantity: kotlin.Int? = null, val quantity: kotlin.Int? = null,
@Json(name = "shipDate") @Contextual @SerialName(value = "shipDate")
val shipDate: java.time.OffsetDateTime? = null, val shipDate: java.time.OffsetDateTime? = null,
/* Order Status */ /* Order Status */
@Json(name = "status") @SerialName(value = "status")
val status: Order.Status? = null, val status: Order.Status? = null,
@Json(name = "complete") @SerialName(value = "complete")
val complete: kotlin.Boolean? = false val complete: kotlin.Boolean? = false
) : Parcelable { ) : Parcelable {
@ -63,12 +70,29 @@ data class Order (
/** /**
* Order Status * Order Status
* *
* Values: placed,approved,delivered * Values: placed,approved,delivered,unknownDefaultOpenApi
*/ */
@Serializable(with = OrderSerializer::class)
enum class Status(val value: kotlin.String) { enum class Status(val value: kotlin.String) {
@Json(name = "placed") placed("placed"), @SerialName(value = "placed") placed("placed"),
@Json(name = "approved") approved("approved"), @SerialName(value = "approved") approved("approved"),
@Json(name = "delivered") delivered("delivered"); @SerialName(value = "delivered") delivered("delivered"),
@SerialName(value = "unknown_default_open_api") unknownDefaultOpenApi("unknown_default_open_api");
}
@Serializer(forClass = Status::class)
internal object StatusSerializer : KSerializer<Status> {
override val descriptor = kotlin.String.serializer().descriptor
override fun deserialize(decoder: Decoder): Status {
val value = decoder.decodeSerializableValue(kotlin.String.serializer())
return Status.values().firstOrNull { it.value == value }
?: Status.unknownDefaultOpenApi
}
override fun serialize(encoder: Encoder, value: Status) {
encoder.encodeSerializableValue(kotlin.String.serializer(), value.value)
}
} }
} }

View File

@ -23,7 +23,14 @@ package org.openapitools.client.models
import org.openapitools.client.models.Category import org.openapitools.client.models.Category
import org.openapitools.client.models.Tag import org.openapitools.client.models.Tag
import com.squareup.moshi.Json import kotlinx.serialization.Serializable
import kotlinx.serialization.SerialName
import kotlinx.serialization.Contextual
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import android.os.Parcelable import android.os.Parcelable
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ -38,26 +45,26 @@ import kotlinx.parcelize.Parcelize
* @param status pet status in the store * @param status pet status in the store
*/ */
@Parcelize @Parcelize
@Serializable
data class Pet ( data class Pet (
@Json(name = "name") @SerialName(value = "name")
val name: kotlin.String, val name: kotlin.String,
@Json(name = "photoUrls") @SerialName(value = "photoUrls")
val photoUrls: kotlin.collections.List<kotlin.String>, val photoUrls: kotlin.collections.List<kotlin.String>,
@Json(name = "id") @SerialName(value = "id")
val id: kotlin.Long? = null, val id: kotlin.Long? = null,
@Json(name = "category") @SerialName(value = "category")
val category: Category? = null, val category: Category? = null,
@Json(name = "tags") @SerialName(value = "tags")
val tags: kotlin.collections.List<Tag>? = null, val tags: kotlin.collections.List<Tag>? = null,
/* pet status in the store */ /* pet status in the store */
@Json(name = "status") @SerialName(value = "status")
val status: Pet.Status? = null val status: Pet.Status? = null
) : Parcelable { ) : Parcelable {
@ -65,12 +72,29 @@ data class Pet (
/** /**
* pet status in the store * pet status in the store
* *
* Values: available,pending,sold * Values: available,pending,sold,unknownDefaultOpenApi
*/ */
@Serializable(with = PetSerializer::class)
enum class Status(val value: kotlin.String) { enum class Status(val value: kotlin.String) {
@Json(name = "available") available("available"), @SerialName(value = "available") available("available"),
@Json(name = "pending") pending("pending"), @SerialName(value = "pending") pending("pending"),
@Json(name = "sold") sold("sold"); @SerialName(value = "sold") sold("sold"),
@SerialName(value = "unknown_default_open_api") unknownDefaultOpenApi("unknown_default_open_api");
}
@Serializer(forClass = Status::class)
internal object StatusSerializer : KSerializer<Status> {
override val descriptor = kotlin.String.serializer().descriptor
override fun deserialize(decoder: Decoder): Status {
val value = decoder.decodeSerializableValue(kotlin.String.serializer())
return Status.values().firstOrNull { it.value == value }
?: Status.unknownDefaultOpenApi
}
override fun serialize(encoder: Encoder, value: Status) {
encoder.encodeSerializableValue(kotlin.String.serializer(), value.value)
}
} }
} }

View File

@ -21,7 +21,14 @@
package org.openapitools.client.models package org.openapitools.client.models
import com.squareup.moshi.Json import kotlinx.serialization.Serializable
import kotlinx.serialization.SerialName
import kotlinx.serialization.Contextual
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import android.os.Parcelable import android.os.Parcelable
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ -32,13 +39,13 @@ import kotlinx.parcelize.Parcelize
* @param name * @param name
*/ */
@Parcelize @Parcelize
@Serializable
data class Tag ( data class Tag (
@Json(name = "id") @SerialName(value = "id")
val id: kotlin.Long? = null, val id: kotlin.Long? = null,
@Json(name = "name") @SerialName(value = "name")
val name: kotlin.String? = null val name: kotlin.String? = null
) : Parcelable ) : Parcelable

View File

@ -21,7 +21,14 @@
package org.openapitools.client.models package org.openapitools.client.models
import com.squareup.moshi.Json import kotlinx.serialization.Serializable
import kotlinx.serialization.SerialName
import kotlinx.serialization.Contextual
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import android.os.Parcelable import android.os.Parcelable
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ -38,32 +45,32 @@ import kotlinx.parcelize.Parcelize
* @param userStatus User Status * @param userStatus User Status
*/ */
@Parcelize @Parcelize
@Serializable
data class User ( data class User (
@Json(name = "id") @SerialName(value = "id")
val id: kotlin.Long? = null, val id: kotlin.Long? = null,
@Json(name = "username") @SerialName(value = "username")
val username: kotlin.String? = null, val username: kotlin.String? = null,
@Json(name = "firstName") @SerialName(value = "firstName")
val firstName: kotlin.String? = null, val firstName: kotlin.String? = null,
@Json(name = "lastName") @SerialName(value = "lastName")
val lastName: kotlin.String? = null, val lastName: kotlin.String? = null,
@Json(name = "email") @SerialName(value = "email")
val email: kotlin.String? = null, val email: kotlin.String? = null,
@Json(name = "password") @SerialName(value = "password")
val password: kotlin.String? = null, val password: kotlin.String? = null,
@Json(name = "phone") @SerialName(value = "phone")
val phone: kotlin.String? = null, val phone: kotlin.String? = null,
/* User Status */ /* User Status */
@Json(name = "userStatus") @SerialName(value = "userStatus")
val userStatus: kotlin.Int? = null val userStatus: kotlin.Int? = null
) : Parcelable ) : Parcelable

View File

@ -16,7 +16,7 @@ import retrofit2.Converter
import retrofit2.converter.scalars.ScalarsConverterFactory import retrofit2.converter.scalars.ScalarsConverterFactory
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import org.openapitools.client.infrastructure.Serializer.jvmJson import org.openapitools.client.infrastructure.Serializer.kotlinxSerializationJson
import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaType
class ApiClient( class ApiClient(
@ -32,7 +32,7 @@ class ApiClient(
Retrofit.Builder() Retrofit.Builder()
.baseUrl(baseUrl) .baseUrl(baseUrl)
.addConverterFactory(ScalarsConverterFactory.create()) .addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(jvmJson.asConverterFactory("application/json".toMediaType())) .addConverterFactory(kotlinxSerializationJson.asConverterFactory("application/json".toMediaType()))
.apply { .apply {
if (converterFactory != null) { if (converterFactory != null) {
addConverterFactory(converterFactory) addConverterFactory(converterFactory)

View File

@ -15,8 +15,13 @@ import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.atomic.AtomicLong import java.util.concurrent.atomic.AtomicLong
object Serializer { object Serializer {
@Deprecated("Use Serializer.kotlinxSerializationAdapters instead", replaceWith = ReplaceWith("Serializer.kotlinxSerializationAdapters"))
@JvmStatic @JvmStatic
val kotlinSerializationAdapters = SerializersModule { val kotlinSerializationAdapters: SerializersModule
get() { return kotlinxSerializationAdapters }
@JvmStatic
val kotlinxSerializationAdapters = SerializersModule {
contextual(BigDecimal::class, BigDecimalAdapter) contextual(BigDecimal::class, BigDecimalAdapter)
contextual(BigInteger::class, BigIntegerAdapter) contextual(BigInteger::class, BigIntegerAdapter)
contextual(LocalDate::class, LocalDateAdapter) contextual(LocalDate::class, LocalDateAdapter)
@ -31,6 +36,17 @@ object Serializer {
contextual(StringBuilder::class, StringBuilderAdapter) contextual(StringBuilder::class, StringBuilderAdapter)
} }
@Deprecated("Use Serializer.kotlinxSerializationJson instead", replaceWith = ReplaceWith("Serializer.kotlinxSerializationJson"))
@JvmStatic @JvmStatic
val jvmJson: Json by lazy { Json { serializersModule = kotlinSerializationAdapters } } val jvmJson: Json
get() { return kotlinxSerializationJson }
@JvmStatic
val kotlinxSerializationJson: Json by lazy {
Json {
serializersModule = kotlinxSerializationAdapters
ignoreUnknownKeys = true
isLenient = true
}
}
} }

View File

@ -6,14 +6,17 @@ gradle/wrapper/gradle-wrapper.jar
gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.properties
gradlew gradlew
gradlew.bat gradlew.bat
proguard-rules.pro
settings.gradle settings.gradle
src/main/kotlin/org/openapitools/client/apis/EnumApi.kt src/main/kotlin/org/openapitools/client/apis/EnumApi.kt
src/main/kotlin/org/openapitools/client/infrastructure/ApiAbstractions.kt src/main/kotlin/org/openapitools/client/infrastructure/ApiAbstractions.kt
src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
src/main/kotlin/org/openapitools/client/infrastructure/ApiResponse.kt src/main/kotlin/org/openapitools/client/infrastructure/ApiResponse.kt
src/main/kotlin/org/openapitools/client/infrastructure/AtomicBooleanAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/AtomicIntegerAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/AtomicLongAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/BigDecimalAdapter.kt src/main/kotlin/org/openapitools/client/infrastructure/BigDecimalAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/BigIntegerAdapter.kt src/main/kotlin/org/openapitools/client/infrastructure/BigIntegerAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/ByteArrayAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/Errors.kt src/main/kotlin/org/openapitools/client/infrastructure/Errors.kt
src/main/kotlin/org/openapitools/client/infrastructure/LocalDateAdapter.kt src/main/kotlin/org/openapitools/client/infrastructure/LocalDateAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/LocalDateTimeAdapter.kt src/main/kotlin/org/openapitools/client/infrastructure/LocalDateTimeAdapter.kt
@ -23,6 +26,8 @@ src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt
src/main/kotlin/org/openapitools/client/infrastructure/RequestMethod.kt src/main/kotlin/org/openapitools/client/infrastructure/RequestMethod.kt
src/main/kotlin/org/openapitools/client/infrastructure/ResponseExtensions.kt src/main/kotlin/org/openapitools/client/infrastructure/ResponseExtensions.kt
src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt
src/main/kotlin/org/openapitools/client/infrastructure/StringBuilderAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/URIAdapter.kt src/main/kotlin/org/openapitools/client/infrastructure/URIAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/URLAdapter.kt
src/main/kotlin/org/openapitools/client/infrastructure/UUIDAdapter.kt src/main/kotlin/org/openapitools/client/infrastructure/UUIDAdapter.kt
src/main/kotlin/org/openapitools/client/models/PetEnum.kt src/main/kotlin/org/openapitools/client/models/PetEnum.kt

View File

@ -14,10 +14,12 @@ buildscript {
} }
dependencies { dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
} }
} }
apply plugin: 'kotlin' apply plugin: 'kotlin'
apply plugin: 'kotlinx-serialization'
repositories { repositories {
maven { url "https://repo1.maven.org/maven2" } maven { url "https://repo1.maven.org/maven2" }
@ -29,9 +31,13 @@ test {
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.1"
implementation "com.squareup.moshi:moshi-kotlin:1.12.0"
implementation "com.squareup.moshi:moshi-adapters:1.12.0"
implementation "com.squareup.okhttp3:okhttp:4.9.1" implementation "com.squareup.okhttp3:okhttp:4.9.1"
testImplementation "io.kotlintest:kotlintest-runner-junit5:3.4.2" testImplementation "io.kotlintest:kotlintest-runner-junit5:3.4.2"
} }
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
kotlinOptions {
freeCompilerArgs += "-Xopt-in=kotlinx.serialization.ExperimentalSerializationApi"
}
}

View File

@ -8,5 +8,7 @@
* `MY_SECOND_VALUE` (value: `"MY_SECOND_VALUE"`) * `MY_SECOND_VALUE` (value: `"MY_SECOND_VALUE"`)
* `UNKNOWN_DEFAULT_OPEN_API` (value: `"unknown_default_open_api"`)

View File

@ -0,0 +1,11 @@
-keepattributes *Annotation*, InnerClasses
-dontnote kotlinx.serialization.AnnotationsKt # core serialization annotations
# kotlinx-serialization-json specific. Add this if you have java.lang.NoClassDefFoundError kotlinx.serialization.json.JsonObjectSerializer
-keepclassmembers class kotlinx.serialization.json.** { *** Companion; }
-keepclasseswithmembers class kotlinx.serialization.json.** { kotlinx.serialization.KSerializer serializer(...); }
# project specific.
-keep,includedescriptorclasses class org.openapitools.client.models.**$$serializer { *; }
-keepclassmembers class org.openapitools.client.models.** { *** Companion; }
-keepclasseswithmembers class org.openapitools.client.models.** { kotlinx.serialization.KSerializer serializer(...); }

View File

@ -25,7 +25,8 @@ import okhttp3.OkHttpClient
import org.openapitools.client.models.PetEnum import org.openapitools.client.models.PetEnum
import com.squareup.moshi.Json import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import org.openapitools.client.infrastructure.ApiClient import org.openapitools.client.infrastructure.ApiClient
import org.openapitools.client.infrastructure.ApiResponse import org.openapitools.client.infrastructure.ApiResponse

View File

@ -27,7 +27,8 @@ import java.time.LocalTime
import java.time.OffsetDateTime import java.time.OffsetDateTime
import java.time.OffsetTime import java.time.OffsetTime
import java.util.Locale import java.util.Locale
import com.squareup.moshi.adapter import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
open class ApiClient(val baseUrl: String, val client: OkHttpClient = defaultClient) { open class ApiClient(val baseUrl: String, val client: OkHttpClient = defaultClient) {
companion object { companion object {
@ -104,7 +105,7 @@ open class ApiClient(val baseUrl: String, val client: OkHttpClient = defaultClie
if (content == null) { if (content == null) {
EMPTY_REQUEST EMPTY_REQUEST
} else { } else {
Serializer.moshi.adapter(T::class.java).toJson(content) Serializer.kotlinxSerializationJson.encodeToString(content)
.toRequestBody((mediaType ?: JsonMediaType).toMediaTypeOrNull()) .toRequestBody((mediaType ?: JsonMediaType).toMediaTypeOrNull())
} }
mediaType == XmlMediaType -> throw UnsupportedOperationException("xml not currently supported.") mediaType == XmlMediaType -> throw UnsupportedOperationException("xml not currently supported.")
@ -112,7 +113,6 @@ open class ApiClient(val baseUrl: String, val client: OkHttpClient = defaultClie
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body and File body.") else -> throw UnsupportedOperationException("requestBody currently only supports JSON body and File body.")
} }
@OptIn(ExperimentalStdlibApi::class)
protected inline fun <reified T: Any?> responseBody(body: ResponseBody?, mediaType: String? = JsonMediaType): T? { protected inline fun <reified T: Any?> responseBody(body: ResponseBody?, mediaType: String? = JsonMediaType): T? {
if(body == null) { if(body == null) {
return null return null
@ -135,7 +135,7 @@ open class ApiClient(val baseUrl: String, val client: OkHttpClient = defaultClie
} }
return when { return when {
mediaType==null || (mediaType.startsWith("application/") && mediaType.endsWith("json")) -> mediaType==null || (mediaType.startsWith("application/") && mediaType.endsWith("json")) ->
Serializer.moshi.adapter<T>().fromJson(bodyContent) Serializer.kotlinxSerializationJson.decodeFromString<T>(bodyContent)
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body.") else -> throw UnsupportedOperationException("responseBody currently only supports JSON body.")
} }
} }
@ -237,6 +237,6 @@ open class ApiClient(val baseUrl: String, val client: OkHttpClient = defaultClie
formatter. It also easily allows to provide a simple way to define a custom date format pattern formatter. It also easily allows to provide a simple way to define a custom date format pattern
inside a gson/moshi adapter. inside a gson/moshi adapter.
*/ */
return Serializer.moshi.adapter(T::class.java).toJson(value).replace("\"", "") return Serializer.kotlinxSerializationJson.encodeToString(value).replace("\"", "")
} }
} }

View File

@ -0,0 +1,21 @@
package org.openapitools.client.infrastructure
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.util.concurrent.atomic.AtomicBoolean
@Serializer(forClass = AtomicBoolean::class)
object AtomicBooleanAdapter : KSerializer<AtomicBoolean> {
override fun serialize(encoder: Encoder, value: AtomicBoolean) {
encoder.encodeBoolean(value.get())
}
override fun deserialize(decoder: Decoder): AtomicBoolean = AtomicBoolean(decoder.decodeBoolean())
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("AtomicBoolean", PrimitiveKind.BOOLEAN)
}

View File

@ -0,0 +1,21 @@
package org.openapitools.client.infrastructure
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.util.concurrent.atomic.AtomicInteger
@Serializer(forClass = AtomicInteger::class)
object AtomicIntegerAdapter : KSerializer<AtomicInteger> {
override fun serialize(encoder: Encoder, value: AtomicInteger) {
encoder.encodeInt(value.get())
}
override fun deserialize(decoder: Decoder): AtomicInteger = AtomicInteger(decoder.decodeInt())
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("AtomicInteger", PrimitiveKind.INT)
}

View File

@ -0,0 +1,21 @@
package org.openapitools.client.infrastructure
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.util.concurrent.atomic.AtomicLong
@Serializer(forClass = AtomicLong::class)
object AtomicLongAdapter : KSerializer<AtomicLong> {
override fun serialize(encoder: Encoder, value: AtomicLong) {
encoder.encodeLong(value.get())
}
override fun deserialize(decoder: Decoder): AtomicLong = AtomicLong(decoder.decodeLong())
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("AtomicLong", PrimitiveKind.LONG)
}

View File

@ -1,17 +1,17 @@
package org.openapitools.client.infrastructure package org.openapitools.client.infrastructure
import com.squareup.moshi.FromJson import kotlinx.serialization.KSerializer
import com.squareup.moshi.ToJson import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.math.BigDecimal import java.math.BigDecimal
class BigDecimalAdapter { @Serializer(forClass = BigDecimal::class)
@ToJson object BigDecimalAdapter : KSerializer<BigDecimal> {
fun toJson(value: BigDecimal): String { override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("BigDecimal", PrimitiveKind.STRING)
return value.toPlainString() override fun deserialize(decoder: Decoder): BigDecimal = BigDecimal(decoder.decodeString())
} override fun serialize(encoder: Encoder, value: BigDecimal) = encoder.encodeString(value.toPlainString())
@FromJson
fun fromJson(value: String): BigDecimal {
return BigDecimal(value)
}
} }

View File

@ -1,17 +1,22 @@
package org.openapitools.client.infrastructure package org.openapitools.client.infrastructure
import com.squareup.moshi.FromJson import kotlinx.serialization.KSerializer
import com.squareup.moshi.ToJson import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.math.BigInteger import java.math.BigInteger
class BigIntegerAdapter { @Serializer(forClass = BigInteger::class)
@ToJson object BigIntegerAdapter : KSerializer<BigInteger> {
fun toJson(value: BigInteger): String { override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("BigInteger", PrimitiveKind.STRING)
return value.toString() override fun deserialize(decoder: Decoder): BigInteger {
return BigInteger(decoder.decodeString())
} }
@FromJson override fun serialize(encoder: Encoder, value: BigInteger) {
fun fromJson(value: String): BigInteger { encoder.encodeString(value.toString())
return BigInteger(value)
} }
} }

View File

@ -1,12 +0,0 @@
package org.openapitools.client.infrastructure
import com.squareup.moshi.FromJson
import com.squareup.moshi.ToJson
class ByteArrayAdapter {
@ToJson
fun toJson(data: ByteArray): String = String(data)
@FromJson
fun fromJson(data: String): ByteArray = data.toByteArray()
}

View File

@ -1,19 +1,24 @@
package org.openapitools.client.infrastructure package org.openapitools.client.infrastructure
import com.squareup.moshi.FromJson import kotlinx.serialization.KSerializer
import com.squareup.moshi.ToJson import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.time.LocalDate import java.time.LocalDate
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
class LocalDateAdapter { @Serializer(forClass = LocalDate::class)
@ToJson object LocalDateAdapter : KSerializer<LocalDate> {
fun toJson(value: LocalDate): String { override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalDate", PrimitiveKind.STRING)
return DateTimeFormatter.ISO_LOCAL_DATE.format(value)
override fun serialize(encoder: Encoder, value: LocalDate) {
encoder.encodeString(DateTimeFormatter.ISO_LOCAL_DATE.format(value))
} }
@FromJson override fun deserialize(decoder: Decoder): LocalDate {
fun fromJson(value: String): LocalDate { return LocalDate.parse(decoder.decodeString(), DateTimeFormatter.ISO_LOCAL_DATE)
return LocalDate.parse(value, DateTimeFormatter.ISO_LOCAL_DATE)
} }
} }

View File

@ -1,19 +1,24 @@
package org.openapitools.client.infrastructure package org.openapitools.client.infrastructure
import com.squareup.moshi.FromJson import kotlinx.serialization.KSerializer
import com.squareup.moshi.ToJson import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
class LocalDateTimeAdapter { @Serializer(forClass = LocalDateTime::class)
@ToJson object LocalDateTimeAdapter : KSerializer<LocalDateTime> {
fun toJson(value: LocalDateTime): String { override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalDateTime", PrimitiveKind.STRING)
return DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(value)
override fun serialize(encoder: Encoder, value: LocalDateTime) {
encoder.encodeString(DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(value))
} }
@FromJson override fun deserialize(decoder: Decoder): LocalDateTime {
fun fromJson(value: String): LocalDateTime { return LocalDateTime.parse(decoder.decodeString(), DateTimeFormatter.ISO_LOCAL_DATE_TIME)
return LocalDateTime.parse(value, DateTimeFormatter.ISO_LOCAL_DATE_TIME)
} }
} }

View File

@ -1,19 +1,24 @@
package org.openapitools.client.infrastructure package org.openapitools.client.infrastructure
import com.squareup.moshi.FromJson import kotlinx.serialization.KSerializer
import com.squareup.moshi.ToJson import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.time.OffsetDateTime import java.time.OffsetDateTime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
class OffsetDateTimeAdapter { @Serializer(forClass = OffsetDateTime::class)
@ToJson object OffsetDateTimeAdapter : KSerializer<OffsetDateTime> {
fun toJson(value: OffsetDateTime): String { override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("OffsetDateTime", PrimitiveKind.STRING)
return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(value)
override fun serialize(encoder: Encoder, value: OffsetDateTime) {
encoder.encodeString(DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(value))
} }
@FromJson override fun deserialize(decoder: Decoder): OffsetDateTime {
fun fromJson(value: String): OffsetDateTime { return OffsetDateTime.parse(decoder.decodeString(), DateTimeFormatter.ISO_OFFSET_DATE_TIME)
return OffsetDateTime.parse(value, DateTimeFormatter.ISO_OFFSET_DATE_TIME)
} }
} }

View File

@ -1,23 +1,52 @@
package org.openapitools.client.infrastructure package org.openapitools.client.infrastructure
import com.squareup.moshi.Moshi import java.math.BigDecimal
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory import java.math.BigInteger
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.OffsetDateTime
import java.util.UUID
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
import java.net.URI
import java.net.URL
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.atomic.AtomicLong
object Serializer { object Serializer {
@Deprecated("Use Serializer.kotlinxSerializationAdapters instead", replaceWith = ReplaceWith("Serializer.kotlinxSerializationAdapters"))
@JvmStatic @JvmStatic
val moshiBuilder: Moshi.Builder = Moshi.Builder() val kotlinSerializationAdapters: SerializersModule
.add(OffsetDateTimeAdapter()) get() { return kotlinxSerializationAdapters }
.add(LocalDateTimeAdapter())
.add(LocalDateAdapter())
.add(UUIDAdapter())
.add(ByteArrayAdapter())
.add(URIAdapter())
.add(KotlinJsonAdapterFactory())
.add(BigDecimalAdapter())
.add(BigIntegerAdapter())
@JvmStatic @JvmStatic
val moshi: Moshi by lazy { val kotlinxSerializationAdapters = SerializersModule {
moshiBuilder.build() contextual(BigDecimal::class, BigDecimalAdapter)
contextual(BigInteger::class, BigIntegerAdapter)
contextual(LocalDate::class, LocalDateAdapter)
contextual(LocalDateTime::class, LocalDateTimeAdapter)
contextual(OffsetDateTime::class, OffsetDateTimeAdapter)
contextual(UUID::class, UUIDAdapter)
contextual(AtomicInteger::class, AtomicIntegerAdapter)
contextual(AtomicLong::class, AtomicLongAdapter)
contextual(AtomicBoolean::class, AtomicBooleanAdapter)
contextual(URI::class, URIAdapter)
contextual(URL::class, URLAdapter)
contextual(StringBuilder::class, StringBuilderAdapter)
}
@Deprecated("Use Serializer.kotlinxSerializationJson instead", replaceWith = ReplaceWith("Serializer.kotlinxSerializationJson"))
@JvmStatic
val jvmJson: Json
get() { return kotlinxSerializationJson }
@JvmStatic
val kotlinxSerializationJson: Json by lazy {
Json {
serializersModule = kotlinxSerializationAdapters
ignoreUnknownKeys = true
isLenient = true
}
} }
} }

View File

@ -0,0 +1,20 @@
package org.openapitools.client.infrastructure
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
@Serializer(forClass = StringBuilder::class)
object StringBuilderAdapter : KSerializer<StringBuilder> {
override fun serialize(encoder: Encoder, value: StringBuilder) {
encoder.encodeString(value.toString())
}
override fun deserialize(decoder: Decoder): StringBuilder = StringBuilder(decoder.decodeString())
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("StringBuilder", PrimitiveKind.STRING)
}

View File

@ -1,13 +1,21 @@
package org.openapitools.client.infrastructure package org.openapitools.client.infrastructure
import com.squareup.moshi.FromJson import kotlinx.serialization.KSerializer
import com.squareup.moshi.ToJson import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.net.URI import java.net.URI
class URIAdapter { @Serializer(forClass = URI::class)
@ToJson object URIAdapter : KSerializer<URI> {
fun toJson(uri: URI) = uri.toString() override fun serialize(encoder: Encoder, value: URI) {
encoder.encodeString(value.toASCIIString())
}
@FromJson override fun deserialize(decoder: Decoder): URI = URI(decoder.decodeString())
fun fromJson(s: String): URI = URI.create(s)
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("URI", PrimitiveKind.STRING)
} }

View File

@ -0,0 +1,21 @@
package org.openapitools.client.infrastructure
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.net.URL
@Serializer(forClass = URL::class)
object URLAdapter : KSerializer<URL> {
override fun serialize(encoder: Encoder, value: URL) {
encoder.encodeString(value.toExternalForm())
}
override fun deserialize(decoder: Decoder): URL = URL(decoder.decodeString())
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("URL", PrimitiveKind.STRING)
}

View File

@ -1,13 +1,23 @@
package org.openapitools.client.infrastructure package org.openapitools.client.infrastructure
import com.squareup.moshi.FromJson import kotlinx.serialization.KSerializer
import com.squareup.moshi.ToJson import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import java.util.UUID import java.util.UUID
class UUIDAdapter { @Serializer(forClass = UUID::class)
@ToJson object UUIDAdapter : KSerializer<UUID> {
fun toJson(uuid: UUID) = uuid.toString() override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("UUID", PrimitiveKind.STRING)
@FromJson override fun serialize(encoder: Encoder, value: UUID) {
fun fromJson(s: String): UUID = UUID.fromString(s) encoder.encodeString(value.toString())
}
override fun deserialize(decoder: Decoder): UUID {
return UUID.fromString(decoder.decodeString())
}
} }

View File

@ -21,21 +21,30 @@
package org.openapitools.client.models package org.openapitools.client.models
import com.squareup.moshi.Json import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
/** /**
* An enum with complex-ish naming * An enum with complex-ish naming
* *
* Values: MY_FIRST_VALUE,MY_SECOND_VALUE * Values: MY_FIRST_VALUE,MY_SECOND_VALUE,UNKNOWN_DEFAULT_OPEN_API
*/ */
@Serializable(with = PetEnumSerializer::class)
enum class PetEnum(val value: kotlin.String) { enum class PetEnum(val value: kotlin.String) {
@Json(name = "myFirstValue") @SerialName(value = "myFirstValue")
MY_FIRST_VALUE("myFirstValue"), MY_FIRST_VALUE("myFirstValue"),
@Json(name = "MY_SECOND_VALUE") @SerialName(value = "MY_SECOND_VALUE")
MY_SECOND_VALUE("MY_SECOND_VALUE"); MY_SECOND_VALUE("MY_SECOND_VALUE"),
@SerialName(value = "unknown_default_open_api")
UNKNOWN_DEFAULT_OPEN_API("unknown_default_open_api");
/** /**
* Override toString() to avoid using the enum variable name as the value, and instead use * Override toString() to avoid using the enum variable name as the value, and instead use
@ -64,3 +73,18 @@ enum class PetEnum(val value: kotlin.String) {
} }
} }
@Serializer(forClass = PetEnum::class)
internal object PetEnumSerializer : KSerializer<PetEnum> {
override val descriptor = kotlin.String.serializer().descriptor
override fun deserialize(decoder: Decoder): PetEnum {
val value = decoder.decodeSerializableValue(kotlin.String.serializer())
return PetEnum.values().firstOrNull { it.value == value }
?: PetEnum.UNKNOWN_DEFAULT_OPEN_API
}
override fun serialize(encoder: Encoder, value: PetEnum) {
encoder.encodeSerializableValue(kotlin.String.serializer(), value.value)
}
}