From 868f4ac7cdd6183a5bd7d87974e1907195d05d48 Mon Sep 17 00:00:00 2001 From: Csaba Kozak Date: Mon, 16 Sep 2024 10:59:20 +0200 Subject: [PATCH] [kotlin-client][multiplatform] add support for kotlinx.datetime.LocalTime --- .../languages/KotlinClientCodegen.java | 10 +++- .../LocalDateAdapter.kt.mustache | 23 +++++++- .../LocalDateTimeAdapter.kt.mustache | 23 +++++++- .../LocalTimeAdapter.kt.mustache | 56 +++++++++++++++++++ .../infrastructure/Serializer.kt.mustache | 5 ++ .../.openapi-generator/FILES | 1 + .../client/infrastructure/LocalDateAdapter.kt | 7 +-- .../infrastructure/LocalDateTimeAdapter.kt | 7 +-- .../client/infrastructure/LocalTimeAdapter.kt | 18 ++++++ .../client/infrastructure/Serializer.kt | 1 + 10 files changed, 134 insertions(+), 17 deletions(-) create mode 100644 modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/LocalTimeAdapter.kt.mustache create mode 100644 samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/LocalTimeAdapter.kt diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java index 6984956674a4..d44ef6fc91e0 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java @@ -583,12 +583,15 @@ private void processKotlinxDate() { typeMapping.put("date-time", "Instant"); typeMapping.put("date", "LocalDate"); + typeMapping.put("time", "LocalTime"); typeMapping.put("DateTime", "Instant"); typeMapping.put("Date", "LocalDate"); + typeMapping.put("Time", "LocalTime"); importMapping.put("Instant", "kotlinx.datetime.Instant"); importMapping.put("LocalDate", "kotlinx.datetime.LocalDate"); + importMapping.put("LocalTime", "kotlinx.datetime.LocalTime"); } private void processJVMRetrofit2Library(String infrastructureFolder) { @@ -654,7 +657,7 @@ private void addSupportingSerializerAdapters(final String infrastructureFolder) supportingFiles.add(new SupportingFile("jvm-common/infrastructure/LocalDateAdapter.kt.mustache", infrastructureFolder, "LocalDateAdapter.kt")); supportingFiles.add(new SupportingFile("jvm-common/infrastructure/LocalDateTimeAdapter.kt.mustache", infrastructureFolder, "LocalDateTimeAdapter.kt")); supportingFiles.add(new SupportingFile("jvm-common/infrastructure/OffsetDateTimeAdapter.kt.mustache", infrastructureFolder, "OffsetDateTimeAdapter.kt")); - addKotlinxDateTimeInstantAdapter(infrastructureFolder); + addKotlinxDateTimeAdapters(infrastructureFolder); supportingFiles.add(new SupportingFile("jvm-common/infrastructure/BigDecimalAdapter.kt.mustache", infrastructureFolder, "BigDecimalAdapter.kt")); supportingFiles.add(new SupportingFile("jvm-common/infrastructure/BigIntegerAdapter.kt.mustache", infrastructureFolder, "BigIntegerAdapter.kt")); supportingFiles.add(new SupportingFile("jvm-common/infrastructure/URIAdapter.kt.mustache", infrastructureFolder, "URIAdapter.kt")); @@ -665,7 +668,7 @@ private void addSupportingSerializerAdapters(final String infrastructureFolder) supportingFiles.add(new SupportingFile("jvm-common/infrastructure/LocalDateAdapter.kt.mustache", infrastructureFolder, "LocalDateAdapter.kt")); supportingFiles.add(new SupportingFile("jvm-common/infrastructure/LocalDateTimeAdapter.kt.mustache", infrastructureFolder, "LocalDateTimeAdapter.kt")); supportingFiles.add(new SupportingFile("jvm-common/infrastructure/OffsetDateTimeAdapter.kt.mustache", infrastructureFolder, "OffsetDateTimeAdapter.kt")); - addKotlinxDateTimeInstantAdapter(infrastructureFolder); + addKotlinxDateTimeAdapters(infrastructureFolder); break; case jackson: @@ -689,9 +692,10 @@ private void addSupportingSerializerAdapters(final String infrastructureFolder) } } - private void addKotlinxDateTimeInstantAdapter(final String infrastructureFolder) { + private void addKotlinxDateTimeAdapters(final String infrastructureFolder) { if (DateLibrary.KOTLINX_DATETIME.value.equals(dateLibrary)) { supportingFiles.add(new SupportingFile("jvm-common/infrastructure/InstantAdapter.kt.mustache", infrastructureFolder, "InstantAdapter.kt")); + supportingFiles.add(new SupportingFile("jvm-common/infrastructure/LocalTimeAdapter.kt.mustache", infrastructureFolder, "LocalTimeAdapter.kt")); } } diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/LocalDateAdapter.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/LocalDateAdapter.kt.mustache index af64f34593b3..6809c74c3a77 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/LocalDateAdapter.kt.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/LocalDateAdapter.kt.mustache @@ -21,36 +21,51 @@ import kotlinx.serialization.descriptors.PrimitiveKind import kotlinx.serialization.descriptors.SerialDescriptor {{/kotlinx_serialization}} {{^threetenbp}} +{{^kotlinx-datetime}} import java.time.LocalDate import java.time.format.DateTimeFormatter +{{/kotlinx-datetime}} {{/threetenbp}} {{#threetenbp}} import org.threeten.bp.LocalDate import org.threeten.bp.format.DateTimeFormatter {{/threetenbp}} +{{#kotlinx-datetime}} +import kotlinx.datetime.LocalDate +{{/kotlinx-datetime}} {{#moshi}} {{#nonPublicApi}}internal {{/nonPublicApi}}class LocalDateAdapter { @ToJson fun toJson(value: LocalDate): String { + {{#kotlinx-datetime}} + return value.toString() + {{/kotlinx-datetime}} + {{^kotlinx-datetime}} return DateTimeFormatter.ISO_LOCAL_DATE.format(value) + {{/kotlinx-datetime}} } @FromJson fun fromJson(value: String): LocalDate { - return LocalDate.parse(value, DateTimeFormatter.ISO_LOCAL_DATE) + return LocalDate.parse(value{{^kotlinx-datetime}}, DateTimeFormatter.ISO_LOCAL_DATE{{/kotlinx-datetime}}) } } {{/moshi}} {{#gson}} -{{#nonPublicApi}}internal {{/nonPublicApi}}class LocalDateAdapter(private val formatter: DateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE) : TypeAdapter() { +{{#nonPublicApi}}internal {{/nonPublicApi}}class LocalDateAdapter({{^kotlinx-datetime}}private val formatter: DateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE{{/kotlinx-datetime}}) : TypeAdapter() { @Throws(IOException::class) override fun write(out: JsonWriter?, value: LocalDate?) { if (value == null) { out?.nullValue() } else { + {{#kotlinx-datetime}} + out?.value(value.toString()) + {{/kotlinx-datetime}} + {{^kotlinx-datetime}} out?.value(formatter.format(value)) + {{/kotlinx-datetime}} } } @@ -64,13 +79,14 @@ import org.threeten.bp.format.DateTimeFormatter return null } else -> { - return LocalDate.parse(out.nextString(), formatter) + return LocalDate.parse(out.nextString(){{^kotlinx-datetime}}, formatter{{/kotlinx-datetime}}) } } } } {{/gson}} {{#kotlinx_serialization}} +{{^kotlinx-datetime}} @Serializer(forClass = LocalDate::class) {{#nonPublicApi}}internal {{/nonPublicApi}}object LocalDateAdapter : KSerializer { override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalDate", PrimitiveKind.STRING) @@ -83,4 +99,5 @@ import org.threeten.bp.format.DateTimeFormatter return LocalDate.parse(decoder.decodeString(), DateTimeFormatter.ISO_LOCAL_DATE) } } +{{/kotlinx-datetime}} {{/kotlinx_serialization}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/LocalDateTimeAdapter.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/LocalDateTimeAdapter.kt.mustache index 96e7168d0b1d..f56cf12d5b77 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/LocalDateTimeAdapter.kt.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/LocalDateTimeAdapter.kt.mustache @@ -21,36 +21,51 @@ import kotlinx.serialization.descriptors.PrimitiveKind import kotlinx.serialization.descriptors.SerialDescriptor {{/kotlinx_serialization}} {{^threetenbp}} +{{^kotlinx-datetime}} import java.time.LocalDateTime import java.time.format.DateTimeFormatter +{{/kotlinx-datetime}} {{/threetenbp}} {{#threetenbp}} import org.threeten.bp.LocalDateTime import org.threeten.bp.format.DateTimeFormatter {{/threetenbp}} +{{#kotlinx-datetime}} +import kotlinx.datetime.LocalDateTime +{{/kotlinx-datetime}} {{#moshi}} {{#nonPublicApi}}internal {{/nonPublicApi}}class LocalDateTimeAdapter { @ToJson fun toJson(value: LocalDateTime): String { + {{#kotlinx-datetime}} + return value.toString() + {{/kotlinx-datetime}} + {{^kotlinx-datetime}} return DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(value) + {{/kotlinx-datetime}} } @FromJson fun fromJson(value: String): LocalDateTime { - return LocalDateTime.parse(value, DateTimeFormatter.ISO_LOCAL_DATE_TIME) + return LocalDateTime.parse(value{{^kotlinx-datetime}}, DateTimeFormatter.ISO_LOCAL_DATE_TIME{{/kotlinx-datetime}}) } } {{/moshi}} {{#gson}} -{{#nonPublicApi}}internal {{/nonPublicApi}}class LocalDateTimeAdapter(private val formatter: DateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME) : TypeAdapter() { +{{#nonPublicApi}}internal {{/nonPublicApi}}class LocalDateTimeAdapter({{^kotlinx-datetime}}private val formatter: DateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME{{/kotlinx-datetime}}) : TypeAdapter() { @Throws(IOException::class) override fun write(out: JsonWriter?, value: LocalDateTime?) { if (value == null) { out?.nullValue() } else { + {{#kotlinx-datetime}} + out?.value(value.toString()) + {{/kotlinx-datetime}} + {{^kotlinx-datetime}} out?.value(formatter.format(value)) + {{/kotlinx-datetime}} } } @@ -64,13 +79,14 @@ import org.threeten.bp.format.DateTimeFormatter return null } else -> { - return LocalDateTime.parse(out.nextString(), formatter) + return LocalDateTime.parse(out.nextString(){{^kotlinx-datetime}}, formatter{{/kotlinx-datetime}}) } } } } {{/gson}} {{#kotlinx_serialization}} +{{^kotlinx-datetime}} @Serializer(forClass = LocalDateTime::class) {{#nonPublicApi}}internal {{/nonPublicApi}}object LocalDateTimeAdapter : KSerializer { override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalDateTime", PrimitiveKind.STRING) @@ -83,4 +99,5 @@ import org.threeten.bp.format.DateTimeFormatter return LocalDateTime.parse(decoder.decodeString(), DateTimeFormatter.ISO_LOCAL_DATE_TIME) } } +{{/kotlinx-datetime}} {{/kotlinx_serialization}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/LocalTimeAdapter.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/LocalTimeAdapter.kt.mustache new file mode 100644 index 000000000000..3a294f8ef7df --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/LocalTimeAdapter.kt.mustache @@ -0,0 +1,56 @@ +package {{packageName}}.infrastructure + +{{#moshi}} +import com.squareup.moshi.FromJson +import com.squareup.moshi.ToJson +{{/moshi}} +{{#gson}} +import com.google.gson.TypeAdapter +import com.google.gson.stream.JsonReader +import com.google.gson.stream.JsonWriter +import com.google.gson.stream.JsonToken.NULL +import java.io.IOException +{{/gson}} +import kotlinx.datetime.LocalTime + +{{#moshi}} +{{#nonPublicApi}}internal {{/nonPublicApi}}class LocalTimeAdapter { + @ToJson + fun toJson(value: LocalTime): String { + return value.toString() + } + + @FromJson + fun fromJson(value: String): LocalTime { + return LocalTime.parse(value) + } + +} +{{/moshi}} +{{#gson}} +{{#nonPublicApi}}internal {{/nonPublicApi}}class LocalTimeAdapter : TypeAdapter() { + @Throws(IOException::class) + override fun write(out: JsonWriter?, value: LocalTime?) { + if (value == null) { + out?.nullValue() + } else { + out?.value(value.toString()) + } + } + + @Throws(IOException::class) + override fun read(out: JsonReader?): LocalTime? { + out ?: return null + + when (out.peek()) { + NULL -> { + out.nextNull() + return null + } + else -> { + return LocalTime.parse(out.nextString()) + } + } + } +} +{{/gson}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/Serializer.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/Serializer.kt.mustache index 57fe58a103f4..67279ee4803d 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/Serializer.kt.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/Serializer.kt.mustache @@ -24,6 +24,7 @@ import org.threeten.bp.OffsetDateTime {{/threetenbp}} {{#kotlinx-datetime}} import kotlinx.datetime.Instant +import kotlinx.datetime.LocalTime {{/kotlinx-datetime}} import java.util.UUID {{/gson}} @@ -66,6 +67,7 @@ import java.util.concurrent.atomic.AtomicLong .add(OffsetDateTimeAdapter()) {{#kotlinx-datetime}} .add(InstantAdapter()) + .add(LocalTimeAdapter()) {{/kotlinx-datetime}} .add(LocalDateTimeAdapter()) .add(LocalDateAdapter()) @@ -92,6 +94,7 @@ import java.util.concurrent.atomic.AtomicLong .registerTypeAdapter(OffsetDateTime::class.java, OffsetDateTimeAdapter()) {{#kotlinx-datetime}} .registerTypeAdapter(Instant::class.java, InstantAdapter()) + .registerTypeAdapter(LocalTime::class.java, LocalTimeAdapter()) {{/kotlinx-datetime}} .registerTypeAdapter(LocalDateTime::class.java, LocalDateTimeAdapter()) .registerTypeAdapter(LocalDate::class.java, LocalDateAdapter()) @@ -122,9 +125,11 @@ import java.util.concurrent.atomic.AtomicLong val kotlinxSerializationAdapters = SerializersModule { contextual(BigDecimal::class, BigDecimalAdapter) contextual(BigInteger::class, BigIntegerAdapter) + {{^kotlinx-datetime}} contextual(LocalDate::class, LocalDateAdapter) contextual(LocalDateTime::class, LocalDateTimeAdapter) contextual(OffsetDateTime::class, OffsetDateTimeAdapter) + {{/kotlinx-datetime}} contextual(UUID::class, UUIDAdapter) contextual(AtomicInteger::class, AtomicIntegerAdapter) contextual(AtomicLong::class, AtomicLongAdapter) diff --git a/samples/client/petstore/kotlin-kotlinx-datetime/.openapi-generator/FILES b/samples/client/petstore/kotlin-kotlinx-datetime/.openapi-generator/FILES index b3104c03efb1..28c33db4a551 100644 --- a/samples/client/petstore/kotlin-kotlinx-datetime/.openapi-generator/FILES +++ b/samples/client/petstore/kotlin-kotlinx-datetime/.openapi-generator/FILES @@ -27,6 +27,7 @@ src/main/kotlin/org/openapitools/client/infrastructure/Errors.kt src/main/kotlin/org/openapitools/client/infrastructure/InstantAdapter.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/LocalTimeAdapter.kt src/main/kotlin/org/openapitools/client/infrastructure/OffsetDateTimeAdapter.kt src/main/kotlin/org/openapitools/client/infrastructure/PartConfig.kt src/main/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt diff --git a/samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateAdapter.kt b/samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateAdapter.kt index b2e1654479a0..505108715e4c 100644 --- a/samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateAdapter.kt +++ b/samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateAdapter.kt @@ -2,18 +2,17 @@ package org.openapitools.client.infrastructure import com.squareup.moshi.FromJson import com.squareup.moshi.ToJson -import java.time.LocalDate -import java.time.format.DateTimeFormatter +import kotlinx.datetime.LocalDate class LocalDateAdapter { @ToJson fun toJson(value: LocalDate): String { - return DateTimeFormatter.ISO_LOCAL_DATE.format(value) + return value.toString() } @FromJson fun fromJson(value: String): LocalDate { - return LocalDate.parse(value, DateTimeFormatter.ISO_LOCAL_DATE) + return LocalDate.parse(value) } } diff --git a/samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateTimeAdapter.kt b/samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateTimeAdapter.kt index e082db94811d..aa8f3907d0d3 100644 --- a/samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateTimeAdapter.kt +++ b/samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateTimeAdapter.kt @@ -2,18 +2,17 @@ package org.openapitools.client.infrastructure import com.squareup.moshi.FromJson import com.squareup.moshi.ToJson -import java.time.LocalDateTime -import java.time.format.DateTimeFormatter +import kotlinx.datetime.LocalDateTime class LocalDateTimeAdapter { @ToJson fun toJson(value: LocalDateTime): String { - return DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(value) + return value.toString() } @FromJson fun fromJson(value: String): LocalDateTime { - return LocalDateTime.parse(value, DateTimeFormatter.ISO_LOCAL_DATE_TIME) + return LocalDateTime.parse(value) } } diff --git a/samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/LocalTimeAdapter.kt b/samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/LocalTimeAdapter.kt new file mode 100644 index 000000000000..7c97c1b8b13b --- /dev/null +++ b/samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/LocalTimeAdapter.kt @@ -0,0 +1,18 @@ +package org.openapitools.client.infrastructure + +import com.squareup.moshi.FromJson +import com.squareup.moshi.ToJson +import kotlinx.datetime.LocalTime + +class LocalTimeAdapter { + @ToJson + fun toJson(value: LocalTime): String { + return value.toString() + } + + @FromJson + fun fromJson(value: String): LocalTime { + return LocalTime.parse(value) + } + +} diff --git a/samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt b/samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt index d191eb67d45d..2e8f453125ba 100644 --- a/samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt +++ b/samples/client/petstore/kotlin-kotlinx-datetime/src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt @@ -8,6 +8,7 @@ object Serializer { val moshiBuilder: Moshi.Builder = Moshi.Builder() .add(OffsetDateTimeAdapter()) .add(InstantAdapter()) + .add(LocalTimeAdapter()) .add(LocalDateTimeAdapter()) .add(LocalDateAdapter()) .add(UUIDAdapter())