diff --git a/.github/workflows/samples-kotlin-client.yaml b/.github/workflows/samples-kotlin-client.yaml index 506e8d3fecd3..7c4fa316aba0 100644 --- a/.github/workflows/samples-kotlin-client.yaml +++ b/.github/workflows/samples-kotlin-client.yaml @@ -11,6 +11,7 @@ on: - 'samples/client/petstore/kotlin*/**' - 'samples/client/others/kotlin-jvm-okhttp-parameter-tests/**' - samples/client/others/kotlin-integer-enum/** + - samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/** jobs: build: @@ -70,6 +71,7 @@ jobs: - samples/client/others/kotlin-integer-enum - samples/client/petstore/kotlin-allOf-discriminator-kotlinx-serialization - samples/client/others/kotlin-oneOf-discriminator-kotlinx-serialization + - samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization steps: - uses: actions/checkout@v5 - uses: actions/setup-java@v5 diff --git a/bin/configs/kotlin-oneOf-anyOf-kotlinx-serialization.yaml b/bin/configs/kotlin-oneOf-anyOf-kotlinx-serialization.yaml new file mode 100644 index 000000000000..9b1d1c2d5614 --- /dev/null +++ b/bin/configs/kotlin-oneOf-anyOf-kotlinx-serialization.yaml @@ -0,0 +1,12 @@ +generatorName: kotlin +outputDir: samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization +inputSpec: modules/openapi-generator/src/test/resources/3_0/kotlin/oneof-anyof-non-discriminator.yaml +templateDir: modules/openapi-generator/src/main/resources/kotlin-client +additionalProperties: + artifactId: kotlin-oneOf-anyOf-kotlinx-serialization + serializableModel: "false" + dateLibrary: java8 + library: jvm-retrofit2 + enumUnknownDefaultCase: true + serializationLibrary: kotlinx_serialization + generateOneOfAnyOfWrappers: true diff --git a/docs/generators/kotlin.md b/docs/generators/kotlin.md index fe2da8f0b41c..5c1a70330b6e 100644 --- a/docs/generators/kotlin.md +++ b/docs/generators/kotlin.md @@ -27,7 +27,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |original| |explicitApi|Generates code with explicit access modifiers to comply with Kotlin Explicit API Mode.| |false| |failOnUnknownProperties|Fail Jackson de-serialization on unknown properties| |false| -|generateOneOfAnyOfWrappers|Generate oneOf, anyOf schemas as wrappers. Only `jvm-retrofit2`(library), `gson`(serializationLibrary) support this option.| |false| +|generateOneOfAnyOfWrappers|Generate oneOf, anyOf schemas as wrappers. Only `jvm-retrofit2`(library) with `gson` or `kotlinx_serialization`(serializationLibrary) support this option.| |false| |generateRoomModels|Generate Android Room database models in addition to API models (JVM Volley library only)| |false| |groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools| |idea|Add IntelliJ Idea plugin and mark Kotlin main and test folders as source folders.| |false| 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 96e402a21be0..e0b51976ce5c 100755 --- 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 @@ -286,7 +286,7 @@ public KotlinClientCodegen() { cliOptions.add(new CliOption(MAP_FILE_BINARY_TO_BYTE_ARRAY, "Map File and Binary to ByteArray (default: false)").defaultValue(Boolean.FALSE.toString())); - cliOptions.add(CliOption.newBoolean(GENERATE_ONEOF_ANYOF_WRAPPERS, "Generate oneOf, anyOf schemas as wrappers. Only `jvm-retrofit2`(library), `gson`(serializationLibrary) support this option.")); + cliOptions.add(CliOption.newBoolean(GENERATE_ONEOF_ANYOF_WRAPPERS, "Generate oneOf, anyOf schemas as wrappers. Only `jvm-retrofit2`(library) with `gson` or `kotlinx_serialization`(serializationLibrary) support this option.")); CliOption serializationLibraryOpt = new CliOption(CodegenConstants.SERIALIZATION_LIBRARY, SERIALIZATION_LIBRARY_DESC); cliOptions.add(serializationLibraryOpt.defaultValue(serializationLibrary.name())); @@ -567,6 +567,7 @@ public void processOpts() { // We replace paths like `/v1/foo/*` with `/v1/foo/<*>` to avoid this additionalProperties.put("sanitizePathComment", new ReplaceAllLambda("\\/\\*", "/<*>")); additionalProperties.put("fnToOneOfWrapperName", new ToOneOfWrapperName()); + additionalProperties.put("fnToValueClassName", new ToValueClassName()); } private void processDateLibrary() { @@ -1155,6 +1156,28 @@ public String formatFragment(String fragment) { } } + private static class ToValueClassName extends CustomLambda { + @Override + public String formatFragment(String fragment) { + // Strip generic type parameters and extract simple class names + // e.g. "kotlin.collections.List" -> "ListStringValue" + // e.g. "kotlin.String" -> "StringValue" + // e.g. "User" -> "UserValue" + StringBuilder sb = new StringBuilder(); + for (String part : fragment.split("[<>,]")) { + String trimmed = part.trim(); + if (trimmed.isEmpty()) continue; + String simpleName = trimmed.contains(".") + ? trimmed.substring(trimmed.lastIndexOf('.') + 1) + : trimmed; + sb.append(Character.toUpperCase(simpleName.charAt(0))); + sb.append(simpleName.substring(1)); + } + sb.append("Value"); + return sb.toString(); + } + } + @Override public void postProcess() { System.out.println("################################################################################"); diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/anyof_class.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/anyof_class.mustache index 213b2fc15645..dfc48ab336b0 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/anyof_class.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/anyof_class.mustache @@ -37,6 +37,25 @@ import kotlinx.serialization.builtins.serializer import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder {{/enumUnknownDefaultCase}} +{{^enumUnknownDefaultCase}} +{{#generateOneOfAnyOfWrappers}} +import kotlinx.serialization.KSerializer +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +{{/generateOneOfAnyOfWrappers}} +{{/enumUnknownDefaultCase}} +{{#generateOneOfAnyOfWrappers}} +import kotlinx.serialization.SerializationException +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.descriptors.buildClassSerialDescriptor +import kotlinx.serialization.json.JsonDecoder +import kotlinx.serialization.json.JsonEncoder +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.decodeFromJsonElement +import kotlinx.serialization.json.encodeToJsonElement +{{/generateOneOfAnyOfWrappers}} {{#hasEnums}} {{/hasEnums}} {{/kotlinx_serialization}} @@ -57,7 +76,9 @@ import java.io.Serializable import {{roomModelPackage}}.{{classname}}RoomModel import {{packageName}}.infrastructure.ITransformForStorage {{/generateRoomModels}} +{{^kotlinx_serialization}} import java.io.IOException +{{/kotlinx_serialization}} /** * {{{description}}} @@ -66,12 +87,144 @@ import java.io.IOException {{#parcelizeModels}} @Parcelize {{/parcelizeModels}} +{{^generateOneOfAnyOfWrappers}} {{#multiplatform}}{{^discriminator}}@Serializable{{/discriminator}}{{/multiplatform}}{{#kotlinx_serialization}}{{#serializableModel}}@KSerializable{{/serializableModel}}{{^serializableModel}}@Serializable{{/serializableModel}}{{/kotlinx_serialization}}{{#moshi}}{{#moshiCodeGen}}@JsonClass(generateAdapter = true){{/moshiCodeGen}}{{/moshi}}{{#jackson}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{/jackson}} +{{/generateOneOfAnyOfWrappers}} +{{#kotlinx_serialization}} +{{#generateOneOfAnyOfWrappers}} +{{#serializableModel}}@KSerializable(with = {{classname}}Serializer::class){{/serializableModel}}{{^serializableModel}}@Serializable(with = {{classname}}Serializer::class){{/serializableModel}} +{{/generateOneOfAnyOfWrappers}} +{{/kotlinx_serialization}} {{#isDeprecated}} @Deprecated(message = "This schema is deprecated.") {{/isDeprecated}} {{>additionalModelTypeAnnotations}} +{{#kotlinx_serialization}} +{{#generateOneOfAnyOfWrappers}} +{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}sealed interface {{classname}} { +{{#composedSchemas}} +{{#anyOf}} +{{^vendorExtensions.x-duplicated-data-type}} + @JvmInline + {{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}value class {{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}}(val value: {{{dataType}}}) : {{classname}} + +{{/vendorExtensions.x-duplicated-data-type}} +{{/anyOf}} +{{/composedSchemas}} +} + +{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}object {{classname}}Serializer : KSerializer<{{classname}}> { + override val descriptor: SerialDescriptor = buildClassSerialDescriptor("{{classname}}") + + override fun serialize(encoder: Encoder, value: {{classname}}) { + val jsonEncoder = encoder as? JsonEncoder ?: throw SerializationException("{{classname}} can only be serialized with Json") + + when (value) { + {{#composedSchemas}} + {{#anyOf}} + {{^vendorExtensions.x-duplicated-data-type}} + {{#isArray}} + is {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}} -> jsonEncoder.encodeJsonElement(jsonEncoder.json.encodeToJsonElement(value.value)) + {{/isArray}} + {{^isArray}} + {{#isPrimitiveType}} + {{#isString}} + is {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}} -> jsonEncoder.encodeString(value.value) + {{/isString}} + {{#isBoolean}} + is {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}} -> jsonEncoder.encodeBoolean(value.value) + {{/isBoolean}} + {{#isInteger}} + {{^isLong}} + is {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}} -> jsonEncoder.encodeInt(value.value) + {{/isLong}} + {{/isInteger}} + {{#isLong}} + is {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}} -> jsonEncoder.encodeLong(value.value) + {{/isLong}} + {{#isNumber}} + {{#isDouble}} + is {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}} -> jsonEncoder.encodeDouble(value.value) + {{/isDouble}} + {{#isFloat}} + is {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}} -> jsonEncoder.encodeFloat(value.value) + {{/isFloat}} + {{/isNumber}} + {{/isPrimitiveType}} + {{^isPrimitiveType}} + is {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}} -> jsonEncoder.encodeSerializableValue({{{dataType}}}.serializer(), value.value) + {{/isPrimitiveType}} + {{/isArray}} + {{/vendorExtensions.x-duplicated-data-type}} + {{/anyOf}} + {{/composedSchemas}} + } + } + + override fun deserialize(decoder: Decoder): {{classname}} { + val jsonDecoder = decoder as? JsonDecoder ?: throw SerializationException("{{classname}} can only be deserialized with Json") + val jsonElement = jsonDecoder.decodeJsonElement() + + val errorMessages = mutableListOf() + + {{#composedSchemas}} + {{#anyOf}} + {{^vendorExtensions.x-duplicated-data-type}} + {{#isArray}} + if (jsonElement is JsonArray) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement<{{{dataType}}}>(jsonElement) + return {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}}(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as {{{dataType}}}: ${e.message}") + } + } + {{/isArray}} + {{^isArray}} + {{#isPrimitiveType}} + {{#isString}} + if (jsonElement is JsonPrimitive && jsonElement.isString) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement<{{{dataType}}}>(jsonElement) + return {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}}(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as {{{dataType}}}: ${e.message}") + } + } + {{/isString}} + {{^isString}} + if (jsonElement is JsonPrimitive && !jsonElement.isString) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement<{{{dataType}}}>(jsonElement) + return {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}}(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as {{{dataType}}}: ${e.message}") + } + } + {{/isString}} + {{/isPrimitiveType}} + {{^isPrimitiveType}} + if (jsonElement !is JsonPrimitive) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement<{{{dataType}}}>(jsonElement) + return {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}}(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as {{{dataType}}}: ${e.message}") + } + } + {{/isPrimitiveType}} + {{/isArray}} + {{/vendorExtensions.x-duplicated-data-type}} + {{/anyOf}} + {{/composedSchemas}} + + throw SerializationException("Cannot deserialize {{classname}}. Tried: ${errorMessages.joinToString(", ")}") + } +} +{{/generateOneOfAnyOfWrappers}} +{{/kotlinx_serialization}} +{{^kotlinx_serialization}} {{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}data class {{classname}}(var actualInstance: Any? = null) { class CustomTypeAdapterFactory : TypeAdapterFactory { @@ -334,4 +487,5 @@ import java.io.IOException } } } -} \ No newline at end of file +} +{{/kotlinx_serialization}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/oneof_class.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/oneof_class.mustache index 6986ff31e043..80b3baa97f60 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/oneof_class.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/oneof_class.mustache @@ -39,22 +39,30 @@ import kotlinx.serialization.encoding.Encoder {{/enumUnknownDefaultCase}} {{^enumUnknownDefaultCase}} {{#generateOneOfAnyOfWrappers}} -{{#discriminator}} import kotlinx.serialization.KSerializer import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -{{/discriminator}} {{/generateOneOfAnyOfWrappers}} {{/enumUnknownDefaultCase}} {{#generateOneOfAnyOfWrappers}} -{{#discriminator}} import kotlinx.serialization.SerializationException import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.buildClassSerialDescriptor import kotlinx.serialization.json.JsonDecoder +{{^discriminator}} +import kotlinx.serialization.json.JsonElement +{{/discriminator}} import kotlinx.serialization.json.JsonEncoder +{{#discriminator}} import kotlinx.serialization.json.JsonObject +{{/discriminator}} import kotlinx.serialization.json.JsonPrimitive +{{^discriminator}} +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.decodeFromJsonElement +import kotlinx.serialization.json.encodeToJsonElement +{{/discriminator}} +{{#discriminator}} import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive {{/discriminator}} @@ -100,6 +108,9 @@ import java.io.IOException {{#discriminator}} @Serializable(with = {{classname}}Serializer::class) {{/discriminator}} +{{^discriminator}} +{{#serializableModel}}@KSerializable(with = {{classname}}Serializer::class){{/serializableModel}}{{^serializableModel}}@Serializable(with = {{classname}}Serializer::class){{/serializableModel}} +{{/discriminator}} {{/generateOneOfAnyOfWrappers}} {{/kotlinx_serialization}} {{#isDeprecated}} @@ -107,6 +118,7 @@ import java.io.IOException {{/isDeprecated}} {{>additionalModelTypeAnnotations}} {{#kotlinx_serialization}} +{{#discriminator}} {{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}sealed interface {{classname}} { {{#discriminator.mappedModels}} @JvmInline @@ -150,6 +162,129 @@ import java.io.IOException } } } +{{/discriminator}} +{{^discriminator}} +{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}sealed interface {{classname}} { +{{#composedSchemas}} +{{#oneOf}} +{{^vendorExtensions.x-duplicated-data-type}} + @JvmInline + {{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}value class {{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}}(val value: {{{dataType}}}) : {{classname}} + +{{/vendorExtensions.x-duplicated-data-type}} +{{/oneOf}} +{{/composedSchemas}} +} + +{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}object {{classname}}Serializer : KSerializer<{{classname}}> { + override val descriptor: SerialDescriptor = buildClassSerialDescriptor("{{classname}}") + + override fun serialize(encoder: Encoder, value: {{classname}}) { + val jsonEncoder = encoder as? JsonEncoder ?: throw SerializationException("{{classname}} can only be serialized with Json") + + when (value) { + {{#composedSchemas}} + {{#oneOf}} + {{^vendorExtensions.x-duplicated-data-type}} + {{#isArray}} + is {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}} -> jsonEncoder.encodeJsonElement(jsonEncoder.json.encodeToJsonElement(value.value)) + {{/isArray}} + {{^isArray}} + {{#isPrimitiveType}} + {{#isString}} + is {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}} -> jsonEncoder.encodeString(value.value) + {{/isString}} + {{#isBoolean}} + is {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}} -> jsonEncoder.encodeBoolean(value.value) + {{/isBoolean}} + {{#isInteger}} + {{^isLong}} + is {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}} -> jsonEncoder.encodeInt(value.value) + {{/isLong}} + {{/isInteger}} + {{#isLong}} + is {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}} -> jsonEncoder.encodeLong(value.value) + {{/isLong}} + {{#isNumber}} + {{#isDouble}} + is {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}} -> jsonEncoder.encodeDouble(value.value) + {{/isDouble}} + {{#isFloat}} + is {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}} -> jsonEncoder.encodeFloat(value.value) + {{/isFloat}} + {{/isNumber}} + {{/isPrimitiveType}} + {{^isPrimitiveType}} + is {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}} -> jsonEncoder.encodeSerializableValue({{{dataType}}}.serializer(), value.value) + {{/isPrimitiveType}} + {{/isArray}} + {{/vendorExtensions.x-duplicated-data-type}} + {{/oneOf}} + {{/composedSchemas}} + } + } + + override fun deserialize(decoder: Decoder): {{classname}} { + val jsonDecoder = decoder as? JsonDecoder ?: throw SerializationException("{{classname}} can only be deserialized with Json") + val jsonElement = jsonDecoder.decodeJsonElement() + + val errorMessages = mutableListOf() + + {{#composedSchemas}} + {{#oneOf}} + {{^vendorExtensions.x-duplicated-data-type}} + {{#isArray}} + if (jsonElement is JsonArray) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement<{{{dataType}}}>(jsonElement) + return {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}}(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as {{{dataType}}}: ${e.message}") + } + } + {{/isArray}} + {{^isArray}} + {{#isPrimitiveType}} + {{#isString}} + if (jsonElement is JsonPrimitive && jsonElement.isString) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement<{{{dataType}}}>(jsonElement) + return {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}}(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as {{{dataType}}}: ${e.message}") + } + } + {{/isString}} + {{^isString}} + if (jsonElement is JsonPrimitive && !jsonElement.isString) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement<{{{dataType}}}>(jsonElement) + return {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}}(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as {{{dataType}}}: ${e.message}") + } + } + {{/isString}} + {{/isPrimitiveType}} + {{^isPrimitiveType}} + if (jsonElement !is JsonPrimitive) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement<{{{dataType}}}>(jsonElement) + return {{classname}}.{{#fnToValueClassName}}{{{dataType}}}{{/fnToValueClassName}}(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as {{{dataType}}}: ${e.message}") + } + } + {{/isPrimitiveType}} + {{/isArray}} + {{/vendorExtensions.x-duplicated-data-type}} + {{/oneOf}} + {{/composedSchemas}} + + throw SerializationException("Cannot deserialize {{classname}}. Tried: ${errorMessages.joinToString(", ")}") + } +} +{{/discriminator}} {{/kotlinx_serialization}} {{^kotlinx_serialization}} {{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}data class {{classname}}(var actualInstance: Any? = null) { diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinClientCodegenModelTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinClientCodegenModelTest.java index 4b844bc3b57f..023374b9e248 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinClientCodegenModelTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinClientCodegenModelTest.java @@ -614,6 +614,76 @@ public void polymorphicKotlinxSerialization() throws IOException { TestUtils.assertFileContains(birdKt, "@SerialName(value = \"BIRD\")"); } + @Test(description = "generate oneOf wrapper with primitive types using kotlinx_serialization") + public void oneOfPrimitiveKotlinxSerialization() throws IOException { + File output = Files.createTempDirectory("test").toFile(); + output.deleteOnExit(); + + final CodegenConfigurator configurator = new CodegenConfigurator() + .setGeneratorName("kotlin") + .setLibrary("jvm-retrofit2") + .setAdditionalProperties(new HashMap<>() {{ + put(CodegenConstants.SERIALIZATION_LIBRARY, "kotlinx_serialization"); + put("generateOneOfAnyOfWrappers", true); + }}) + .setInputSpec("src/test/resources/3_0/issue_19942.json") + .setOutputDir(output.getAbsolutePath().replace("\\", "/")); + + final ClientOptInput clientOptInput = configurator.toClientOptInput(); + DefaultGenerator generator = new DefaultGenerator(); + generator.opts(clientOptInput).generate(); + + final Path oneOfModelKt = Paths.get(output + "/src/main/kotlin/org/openapitools/client/models/ObjectWithComplexOneOfId.kt"); + // generates sealed interface (not data class) + TestUtils.assertFileContains(oneOfModelKt, "sealed interface ObjectWithComplexOneOfId"); + // has value class variants + TestUtils.assertFileContains(oneOfModelKt, "value class StringValue(val value: kotlin.String) : ObjectWithComplexOneOfId"); + // has a custom KSerializer + TestUtils.assertFileContains(oneOfModelKt, "object ObjectWithComplexOneOfIdSerializer : KSerializer"); + // serializer handles primitive types via value class pattern + TestUtils.assertFileContains(oneOfModelKt, "is ObjectWithComplexOneOfId.StringValue -> jsonEncoder.encodeString(value.value)"); + // deserializer uses type guards + TestUtils.assertFileContains(oneOfModelKt, "jsonElement is JsonPrimitive && jsonElement.isString"); + // parent model references the oneOf wrapper type + final Path parentModelKt = Paths.get(output + "/src/main/kotlin/org/openapitools/client/models/ObjectWithComplexOneOf.kt"); + TestUtils.assertFileContains(parentModelKt, "val id: ObjectWithComplexOneOfId?"); + } + + @Test(description = "generate anyOf wrapper with primitive types using kotlinx_serialization") + public void anyOfPrimitiveKotlinxSerialization() throws IOException { + File output = Files.createTempDirectory("test").toFile(); + output.deleteOnExit(); + + final CodegenConfigurator configurator = new CodegenConfigurator() + .setGeneratorName("kotlin") + .setLibrary("jvm-retrofit2") + .setAdditionalProperties(new HashMap<>() {{ + put(CodegenConstants.SERIALIZATION_LIBRARY, "kotlinx_serialization"); + put("generateOneOfAnyOfWrappers", true); + }}) + .setInputSpec("src/test/resources/3_0/issue_19942.json") + .setOutputDir(output.getAbsolutePath().replace("\\", "/")); + + final ClientOptInput clientOptInput = configurator.toClientOptInput(); + DefaultGenerator generator = new DefaultGenerator(); + generator.opts(clientOptInput).generate(); + + final Path anyOfModelKt = Paths.get(output + "/src/main/kotlin/org/openapitools/client/models/ObjectWithComplexAnyOfId.kt"); + // generates sealed interface (not data class) + TestUtils.assertFileContains(anyOfModelKt, "sealed interface ObjectWithComplexAnyOfId"); + // has value class variants + TestUtils.assertFileContains(anyOfModelKt, "value class StringValue(val value: kotlin.String) : ObjectWithComplexAnyOfId"); + // has a custom KSerializer + TestUtils.assertFileContains(anyOfModelKt, "object ObjectWithComplexAnyOfIdSerializer : KSerializer"); + // serializer handles primitive types via value class pattern + TestUtils.assertFileContains(anyOfModelKt, "is ObjectWithComplexAnyOfId.StringValue -> jsonEncoder.encodeString(value.value)"); + // deserializer uses type guards + TestUtils.assertFileContains(anyOfModelKt, "jsonElement is JsonPrimitive && jsonElement.isString"); + // parent model references the anyOf wrapper type + final Path parentModelKt = Paths.get(output + "/src/main/kotlin/org/openapitools/client/models/ObjectWithComplexAnyOf.kt"); + TestUtils.assertFileContains(parentModelKt, "val id: ObjectWithComplexAnyOfId?"); + } + @Test(description = "generate polymorphic jackson model") public void polymorphicJacksonSerialization() throws IOException { File output = Files.createTempDirectory("test").toFile(); diff --git a/modules/openapi-generator/src/test/resources/3_0/kotlin/oneof-anyof-non-discriminator.yaml b/modules/openapi-generator/src/test/resources/3_0/kotlin/oneof-anyof-non-discriminator.yaml new file mode 100644 index 000000000000..c15a50e2c3c6 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/kotlin/oneof-anyof-non-discriminator.yaml @@ -0,0 +1,138 @@ +openapi: 3.0.1 +info: + title: oneOf/anyOf non-discriminator example + description: Test non-discriminator oneOf and anyOf with model, primitive, and array types + version: '0.1' +servers: + - url: http://example.org +tags: + - name: test +paths: + '/v1/test/oneOf': + get: + tags: + - test + operationId: get-oneOf + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/UserOrPet' + '/v1/test/oneOfArray': + get: + tags: + - test + operationId: get-oneOf-array + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/UserOrPetOrArrayString' + '/v1/test/oneOfPrimitive': + get: + tags: + - test + operationId: get-oneOf-primitive + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/StringOrLong' + '/v1/test/oneOfBooleanPrimitive': + get: + tags: + - test + operationId: get-oneOf-boolean-primitive + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/BooleanOrLong' + '/v1/test/anyOf': + get: + tags: + - test + operationId: get-anyOf + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/AnyOfUserOrPet' + '/v1/test/anyOfArray': + get: + tags: + - test + operationId: get-anyOf-array + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/AnyOfUserOrPetOrArrayString' +components: + schemas: + User: + type: object + properties: + id: + type: integer + format: int64 + username: + type: string + required: + - id + - username + Pet: + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + required: + - id + - name + UserOrPet: + oneOf: + - $ref: '#/components/schemas/User' + - $ref: '#/components/schemas/Pet' + UserOrPetOrArrayString: + oneOf: + - $ref: '#/components/schemas/User' + - $ref: '#/components/schemas/Pet' + - type: array + items: + type: string + StringOrLong: + oneOf: + - type: string + - type: integer + format: int64 + BooleanOrLong: + oneOf: + - type: boolean + - type: integer + format: int64 + AnyOfUserOrPet: + anyOf: + - $ref: '#/components/schemas/User' + - $ref: '#/components/schemas/Pet' + AnyOfUserOrPetOrArrayString: + anyOf: + - $ref: '#/components/schemas/User' + - $ref: '#/components/schemas/Pet' + - type: array + items: + type: string diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/.openapi-generator-ignore b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/.openapi-generator-ignore new file mode 100644 index 000000000000..7484ee590a38 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/.openapi-generator/FILES b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/.openapi-generator/FILES new file mode 100644 index 000000000000..3cff65854d3d --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/.openapi-generator/FILES @@ -0,0 +1,42 @@ +README.md +build.gradle +docs/AnyOfUserOrPet.md +docs/AnyOfUserOrPetOrArrayString.md +docs/BooleanOrLong.md +docs/Pet.md +docs/StringOrLong.md +docs/TestApi.md +docs/User.md +docs/UserOrPet.md +docs/UserOrPetOrArrayString.md +gradle/wrapper/gradle-wrapper.jar +gradle/wrapper/gradle-wrapper.properties +gradlew +gradlew.bat +proguard-rules.pro +settings.gradle +src/main/kotlin/org/openapitools/client/apis/TestApi.kt +src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.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/BigIntegerAdapter.kt +src/main/kotlin/org/openapitools/client/infrastructure/CollectionFormats.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/OffsetDateTimeAdapter.kt +src/main/kotlin/org/openapitools/client/infrastructure/ResponseExt.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/URLAdapter.kt +src/main/kotlin/org/openapitools/client/infrastructure/UUIDAdapter.kt +src/main/kotlin/org/openapitools/client/models/AnyOfUserOrPet.kt +src/main/kotlin/org/openapitools/client/models/AnyOfUserOrPetOrArrayString.kt +src/main/kotlin/org/openapitools/client/models/BooleanOrLong.kt +src/main/kotlin/org/openapitools/client/models/Pet.kt +src/main/kotlin/org/openapitools/client/models/StringOrLong.kt +src/main/kotlin/org/openapitools/client/models/User.kt +src/main/kotlin/org/openapitools/client/models/UserOrPet.kt +src/main/kotlin/org/openapitools/client/models/UserOrPetOrArrayString.kt diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/.openapi-generator/VERSION b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/.openapi-generator/VERSION new file mode 100644 index 000000000000..0610c66bc14f --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.21.0-SNAPSHOT diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/README.md b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/README.md new file mode 100644 index 000000000000..a5734ec4140e --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/README.md @@ -0,0 +1,73 @@ +# org.openapitools.client - Kotlin client library for oneOf/anyOf non-discriminator example + +Test non-discriminator oneOf and anyOf with model, primitive, and array types + +## Overview +This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [openapi-spec](https://github.com/OAI/OpenAPI-Specification) from a remote server, you can easily generate an API client. + +- API version: 0.1 +- Package version: +- Generator version: 7.21.0-SNAPSHOT +- Build package: org.openapitools.codegen.languages.KotlinClientCodegen + +## Requires + +* Kotlin 2.2.20 +* Gradle 8.14 + +## Build + +First, create the gradle wrapper script: + +``` +gradle wrapper +``` + +Then, run: + +``` +./gradlew check assemble +``` + +This runs all tests and packages the library. + +## Features/Implementation Notes + +* Supports JSON inputs/outputs, File inputs, and Form inputs. +* Supports collection formats for query parameters: csv, tsv, ssv, pipes. +* Some Kotlin and Java types are fully qualified to avoid conflicts with types defined in OpenAPI definitions. +* Implementation of ApiClient is intended to reduce method counts, specifically to benefit Android targets. + + +## Documentation for API Endpoints + +All URIs are relative to *http://example.org* + +| Class | Method | HTTP request | Description | +| ------------ | ------------- | ------------- | ------------- | +| *TestApi* | [**getAnyOf**](docs/TestApi.md#getanyof) | **GET** v1/test/anyOf | | +| *TestApi* | [**getAnyOfArray**](docs/TestApi.md#getanyofarray) | **GET** v1/test/anyOfArray | | +| *TestApi* | [**getOneOf**](docs/TestApi.md#getoneof) | **GET** v1/test/oneOf | | +| *TestApi* | [**getOneOfArray**](docs/TestApi.md#getoneofarray) | **GET** v1/test/oneOfArray | | +| *TestApi* | [**getOneOfBooleanPrimitive**](docs/TestApi.md#getoneofbooleanprimitive) | **GET** v1/test/oneOfBooleanPrimitive | | +| *TestApi* | [**getOneOfPrimitive**](docs/TestApi.md#getoneofprimitive) | **GET** v1/test/oneOfPrimitive | | + + + +## Documentation for Models + + - [org.openapitools.client.models.AnyOfUserOrPet](docs/AnyOfUserOrPet.md) + - [org.openapitools.client.models.AnyOfUserOrPetOrArrayString](docs/AnyOfUserOrPetOrArrayString.md) + - [org.openapitools.client.models.BooleanOrLong](docs/BooleanOrLong.md) + - [org.openapitools.client.models.Pet](docs/Pet.md) + - [org.openapitools.client.models.StringOrLong](docs/StringOrLong.md) + - [org.openapitools.client.models.User](docs/User.md) + - [org.openapitools.client.models.UserOrPet](docs/UserOrPet.md) + - [org.openapitools.client.models.UserOrPetOrArrayString](docs/UserOrPetOrArrayString.md) + + + +## Documentation for Authorization + +Endpoints do not require authorization. + diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/build.gradle b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/build.gradle new file mode 100644 index 000000000000..0f176ff525b7 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/build.gradle @@ -0,0 +1,87 @@ +group 'org.openapitools' +version '1.0.0' + +wrapper { + gradleVersion = '8.14.3' + distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip" +} + +buildscript { + ext.kotlin_version = '2.2.20' + ext.retrofitVersion = '3.0.0' + ext.spotless_version = "7.2.1" + + repositories { + maven { url "https://repo1.maven.org/maven2" } + } + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version" + classpath "com.diffplug.spotless:spotless-plugin-gradle:$spotless_version" + } +} + +apply plugin: 'kotlin' +apply plugin: 'kotlinx-serialization' +apply plugin: 'maven-publish' +apply plugin: 'com.diffplug.spotless' + +repositories { + maven { url "https://repo1.maven.org/maven2" } +} + +// Use spotless plugin to automatically format code, remove unused import, etc +// To apply changes directly to the file, run `gradlew spotlessApply` +// Ref: https://github.com/diffplug/spotless/tree/main/plugin-gradle +spotless { + // comment out below to run spotless as part of the `check` task + enforceCheck false + + format 'misc', { + // define the files (e.g. '*.gradle', '*.md') to apply `misc` to + target '.gitignore' + + // define the steps to apply to those files + trimTrailingWhitespace() + indentWithSpaces() // Takes an integer argument if you don't like 4 + endWithNewline() + } + kotlin { + ktfmt() + } +} + +test { + useJUnitPlatform() +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" + implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0" + implementation "com.squareup.okhttp3:logging-interceptor:5.1.0" + implementation "com.squareup.retrofit2:retrofit:$retrofitVersion" + implementation "com.squareup.retrofit2:converter-kotlinx-serialization:$retrofitVersion" + implementation "com.squareup.retrofit2:converter-scalars:$retrofitVersion" + 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" + } +} + +java { + withSourcesJar() +} + +publishing { + publications { + maven(MavenPublication) { + groupId = 'org.openapitools' + artifactId = 'kotlin-oneOf-anyOf-kotlinx-serialization' + version = '1.0.0' + from components.java + } + } +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/AnyOfUserOrPet.md b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/AnyOfUserOrPet.md new file mode 100644 index 000000000000..bfa4bc532462 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/AnyOfUserOrPet.md @@ -0,0 +1,12 @@ + +# AnyOfUserOrPet + +## Properties +| Name | Type | Description | Notes | +| ------------ | ------------- | ------------- | ------------- | +| **id** | **kotlin.Long** | | | +| **username** | **kotlin.String** | | | +| **name** | **kotlin.String** | | | + + + diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/AnyOfUserOrPetOrArrayString.md b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/AnyOfUserOrPetOrArrayString.md new file mode 100644 index 000000000000..fa7a5106fa49 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/AnyOfUserOrPetOrArrayString.md @@ -0,0 +1,12 @@ + +# AnyOfUserOrPetOrArrayString + +## Properties +| Name | Type | Description | Notes | +| ------------ | ------------- | ------------- | ------------- | +| **id** | **kotlin.Long** | | | +| **username** | **kotlin.String** | | | +| **name** | **kotlin.String** | | | + + + diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/BooleanOrLong.md b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/BooleanOrLong.md new file mode 100644 index 000000000000..5bff5784707b --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/BooleanOrLong.md @@ -0,0 +1,9 @@ + +# BooleanOrLong + +## Properties +| Name | Type | Description | Notes | +| ------------ | ------------- | ------------- | ------------- | + + + diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/Pet.md b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/Pet.md new file mode 100644 index 000000000000..ca97066a6232 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/Pet.md @@ -0,0 +1,11 @@ + +# Pet + +## Properties +| Name | Type | Description | Notes | +| ------------ | ------------- | ------------- | ------------- | +| **id** | **kotlin.Long** | | | +| **name** | **kotlin.String** | | | + + + diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/StringOrLong.md b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/StringOrLong.md new file mode 100644 index 000000000000..ca17013a8b34 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/StringOrLong.md @@ -0,0 +1,9 @@ + +# StringOrLong + +## Properties +| Name | Type | Description | Notes | +| ------------ | ------------- | ------------- | ------------- | + + + diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/TestApi.md b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/TestApi.md new file mode 100644 index 000000000000..310ca6a6acb7 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/TestApi.md @@ -0,0 +1,206 @@ +# TestApi + +All URIs are relative to *http://example.org* + +| Method | HTTP request | Description | +| ------------- | ------------- | ------------- | +| [**getAnyOf**](TestApi.md#getAnyOf) | **GET** v1/test/anyOf | | +| [**getAnyOfArray**](TestApi.md#getAnyOfArray) | **GET** v1/test/anyOfArray | | +| [**getOneOf**](TestApi.md#getOneOf) | **GET** v1/test/oneOf | | +| [**getOneOfArray**](TestApi.md#getOneOfArray) | **GET** v1/test/oneOfArray | | +| [**getOneOfBooleanPrimitive**](TestApi.md#getOneOfBooleanPrimitive) | **GET** v1/test/oneOfBooleanPrimitive | | +| [**getOneOfPrimitive**](TestApi.md#getOneOfPrimitive) | **GET** v1/test/oneOfPrimitive | | + + + + + +### Example +```kotlin +// Import classes: +//import org.openapitools.client.* +//import org.openapitools.client.infrastructure.* +//import org.openapitools.client.models.* + +val apiClient = ApiClient() +val webService = apiClient.createWebservice(TestApi::class.java) + +val result : AnyOfUserOrPet = webService.getAnyOf() +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**AnyOfUserOrPet**](AnyOfUserOrPet.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + + + + +### Example +```kotlin +// Import classes: +//import org.openapitools.client.* +//import org.openapitools.client.infrastructure.* +//import org.openapitools.client.models.* + +val apiClient = ApiClient() +val webService = apiClient.createWebservice(TestApi::class.java) + +val result : AnyOfUserOrPetOrArrayString = webService.getAnyOfArray() +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**AnyOfUserOrPetOrArrayString**](AnyOfUserOrPetOrArrayString.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + + + + +### Example +```kotlin +// Import classes: +//import org.openapitools.client.* +//import org.openapitools.client.infrastructure.* +//import org.openapitools.client.models.* + +val apiClient = ApiClient() +val webService = apiClient.createWebservice(TestApi::class.java) + +val result : UserOrPet = webService.getOneOf() +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**UserOrPet**](UserOrPet.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + + + + +### Example +```kotlin +// Import classes: +//import org.openapitools.client.* +//import org.openapitools.client.infrastructure.* +//import org.openapitools.client.models.* + +val apiClient = ApiClient() +val webService = apiClient.createWebservice(TestApi::class.java) + +val result : UserOrPetOrArrayString = webService.getOneOfArray() +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**UserOrPetOrArrayString**](UserOrPetOrArrayString.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + + + + +### Example +```kotlin +// Import classes: +//import org.openapitools.client.* +//import org.openapitools.client.infrastructure.* +//import org.openapitools.client.models.* + +val apiClient = ApiClient() +val webService = apiClient.createWebservice(TestApi::class.java) + +val result : BooleanOrLong = webService.getOneOfBooleanPrimitive() +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**BooleanOrLong**](BooleanOrLong.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + + + + +### Example +```kotlin +// Import classes: +//import org.openapitools.client.* +//import org.openapitools.client.infrastructure.* +//import org.openapitools.client.models.* + +val apiClient = ApiClient() +val webService = apiClient.createWebservice(TestApi::class.java) + +val result : StringOrLong = webService.getOneOfPrimitive() +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**StringOrLong**](StringOrLong.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/User.md b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/User.md new file mode 100644 index 000000000000..ff40c0f8236e --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/User.md @@ -0,0 +1,11 @@ + +# User + +## Properties +| Name | Type | Description | Notes | +| ------------ | ------------- | ------------- | ------------- | +| **id** | **kotlin.Long** | | | +| **username** | **kotlin.String** | | | + + + diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/UserOrPet.md b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/UserOrPet.md new file mode 100644 index 000000000000..1cfb30b0d0a9 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/UserOrPet.md @@ -0,0 +1,12 @@ + +# UserOrPet + +## Properties +| Name | Type | Description | Notes | +| ------------ | ------------- | ------------- | ------------- | +| **id** | **kotlin.Long** | | | +| **username** | **kotlin.String** | | | +| **name** | **kotlin.String** | | | + + + diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/UserOrPetOrArrayString.md b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/UserOrPetOrArrayString.md new file mode 100644 index 000000000000..667f64035f8f --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/docs/UserOrPetOrArrayString.md @@ -0,0 +1,12 @@ + +# UserOrPetOrArrayString + +## Properties +| Name | Type | Description | Notes | +| ------------ | ------------- | ------------- | ------------- | +| **id** | **kotlin.Long** | | | +| **username** | **kotlin.String** | | | +| **name** | **kotlin.String** | | | + + + diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/gradle/wrapper/gradle-wrapper.jar b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000000..2c3521197d7c Binary files /dev/null and b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/gradle/wrapper/gradle-wrapper.jar differ diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/gradle/wrapper/gradle-wrapper.properties b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000000..7705927e949f --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/gradlew b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/gradlew new file mode 100755 index 000000000000..51eb8bb47109 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/gradlew @@ -0,0 +1,252 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while +APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path +[ -h "$app_path" ] +do +ls=$( ls -ld "$app_path" ) +link=${ls#*' -> '} +case $link in #( +/*) app_path=$link ;; #( +*) app_path=$APP_HOME$link ;; +esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { +echo "$*" +} >&2 + +die () { +echo +echo "$*" +echo +exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( +CYGWIN* ) cygwin=true ;; #( +Darwin* ) darwin=true ;; #( +MSYS* | MINGW* ) msys=true ;; #( +NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then +if [ -x "$JAVA_HOME/jre/sh/java" ] ; then +# IBM's JDK on AIX uses strange locations for the executables +JAVACMD=$JAVA_HOME/jre/sh/java +else +JAVACMD=$JAVA_HOME/bin/java +fi +if [ ! -x "$JAVACMD" ] ; then +die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi +else +JAVACMD=java +if ! command -v java >/dev/null 2>&1 +then +die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then +case $MAX_FD in #( +max*) +# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. +# shellcheck disable=SC2039,SC3045 +MAX_FD=$( ulimit -H -n ) || +warn "Could not query maximum file descriptor limit" +esac +case $MAX_FD in #( +'' | soft) :;; #( +*) +# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. +# shellcheck disable=SC2039,SC3045 +ulimit -n "$MAX_FD" || +warn "Could not set maximum file descriptor limit to $MAX_FD" +esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then +APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) +CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + +JAVACMD=$( cygpath --unix "$JAVACMD" ) + +# Now convert the arguments - kludge to limit ourselves to /bin/sh +for arg do +if +case $arg in #( +-*) false ;; # don't mess with options #( +/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath +[ -e "$t" ] ;; #( +*) false ;; +esac +then +arg=$( cygpath --path --ignore --mixed "$arg" ) +fi +# Roll the args list around exactly as many times as the number of +# args, so each arg winds up back in the position where it started, but +# possibly modified. +# +# NB: a `for` loop captures its iteration list before it begins, so +# changing the positional parameters here affects neither the number of +# iterations, nor the values presented in `arg`. +shift # remove old arg +set -- "$@" "$arg" # push replacement arg +done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ +"-Dorg.gradle.appname=$APP_BASE_NAME" \ +-classpath "$CLASSPATH" \ +org.gradle.wrapper.GradleWrapperMain \ +"$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then +die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( +printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | +xargs -n1 | +sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | +tr '\n' ' ' +)" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/gradlew.bat b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/gradlew.bat new file mode 100644 index 000000000000..9d21a21834d5 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/proguard-rules.pro b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/proguard-rules.pro new file mode 100644 index 000000000000..7c7b08bf3810 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/proguard-rules.pro @@ -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(...); } diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/settings.gradle b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/settings.gradle new file mode 100644 index 000000000000..a1178cffa7c1 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'kotlin-oneOf-anyOf-kotlinx-serialization' diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/apis/TestApi.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/apis/TestApi.kt new file mode 100644 index 000000000000..c8efb8289cac --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/apis/TestApi.kt @@ -0,0 +1,90 @@ +package org.openapitools.client.apis + +import org.openapitools.client.infrastructure.CollectionFormats.* +import retrofit2.http.* +import retrofit2.Call +import okhttp3.RequestBody +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +import org.openapitools.client.models.AnyOfUserOrPet +import org.openapitools.client.models.AnyOfUserOrPetOrArrayString +import org.openapitools.client.models.BooleanOrLong +import org.openapitools.client.models.StringOrLong +import org.openapitools.client.models.UserOrPet +import org.openapitools.client.models.UserOrPetOrArrayString + +interface TestApi { + /** + * GET v1/test/anyOf + * + * + * Responses: + * - 200: OK + * + * @return [Call]<[AnyOfUserOrPet]> + */ + @GET("v1/test/anyOf") + fun getAnyOf(): Call + + /** + * GET v1/test/anyOfArray + * + * + * Responses: + * - 200: OK + * + * @return [Call]<[AnyOfUserOrPetOrArrayString]> + */ + @GET("v1/test/anyOfArray") + fun getAnyOfArray(): Call + + /** + * GET v1/test/oneOf + * + * + * Responses: + * - 200: OK + * + * @return [Call]<[UserOrPet]> + */ + @GET("v1/test/oneOf") + fun getOneOf(): Call + + /** + * GET v1/test/oneOfArray + * + * + * Responses: + * - 200: OK + * + * @return [Call]<[UserOrPetOrArrayString]> + */ + @GET("v1/test/oneOfArray") + fun getOneOfArray(): Call + + /** + * GET v1/test/oneOfBooleanPrimitive + * + * + * Responses: + * - 200: OK + * + * @return [Call]<[BooleanOrLong]> + */ + @GET("v1/test/oneOfBooleanPrimitive") + fun getOneOfBooleanPrimitive(): Call + + /** + * GET v1/test/oneOfPrimitive + * + * + * Responses: + * - 200: OK + * + * @return [Call]<[StringOrLong]> + */ + @GET("v1/test/oneOfPrimitive") + fun getOneOfPrimitive(): Call + +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt new file mode 100644 index 000000000000..556870f29311 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt @@ -0,0 +1,111 @@ +package org.openapitools.client.infrastructure + + +import okhttp3.Call +import okhttp3.Interceptor +import okhttp3.OkHttpClient +import retrofit2.Retrofit +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Converter +import retrofit2.CallAdapter +import retrofit2.converter.scalars.ScalarsConverterFactory + +import retrofit2.converter.kotlinx.serialization.asConverterFactory +import org.openapitools.client.infrastructure.Serializer.kotlinxSerializationJson +import okhttp3.MediaType.Companion.toMediaType + +class ApiClient( + private var baseUrl: String = defaultBasePath, + private val okHttpClientBuilder: OkHttpClient.Builder? = null, + private val callFactory: Call.Factory? = null, + private val callAdapterFactories: List = listOf( + ), + private val converterFactories: List = listOf( + ScalarsConverterFactory.create(), + kotlinxSerializationJson.asConverterFactory("application/json".toMediaType()), + ) +) { + private val apiAuthorizations = mutableMapOf() + var logger: ((String) -> Unit)? = null + + private val retrofitBuilder: Retrofit.Builder by lazy { + Retrofit.Builder() + .baseUrl(baseUrl) + .apply { + callAdapterFactories.forEach { + addCallAdapterFactory(it) + } + } + .apply { + converterFactories.forEach { + addConverterFactory(it) + } + } + } + + private val clientBuilder: OkHttpClient.Builder by lazy { + okHttpClientBuilder ?: defaultClientBuilder + } + + private val defaultClientBuilder: OkHttpClient.Builder by lazy { + OkHttpClient() + .newBuilder() + .addInterceptor(HttpLoggingInterceptor { message -> logger?.invoke(message) } + .apply { level = HttpLoggingInterceptor.Level.BODY } + ) + } + + init { + normalizeBaseUrl() + } + + /** + * Adds an authorization to be used by the client + * @param authName Authentication name + * @param authorization Authorization interceptor + * @return ApiClient + */ + fun addAuthorization(authName: String, authorization: Interceptor): ApiClient { + if (apiAuthorizations.containsKey(authName)) { + throw RuntimeException("auth name $authName already in api authorizations") + } + apiAuthorizations[authName] = authorization + clientBuilder.addInterceptor(authorization) + return this + } + + fun setLogger(logger: (String) -> Unit): ApiClient { + this.logger = logger + return this + } + + fun createService(serviceClass: Class): S { + val usedCallFactory = this.callFactory ?: clientBuilder.build() + return retrofitBuilder.callFactory(usedCallFactory).build().create(serviceClass) + } + + private fun normalizeBaseUrl() { + if (!baseUrl.endsWith("/")) { + baseUrl += "/" + } + } + + private inline fun Iterable.runOnFirst(callback: U.() -> Unit) { + for (element in this) { + if (element is U) { + callback.invoke(element) + break + } + } + } + + companion object { + @JvmStatic + protected val baseUrlKey: String = "org.openapitools.client.baseUrl" + + @JvmStatic + val defaultBasePath: String by lazy { + System.getProperties().getProperty(baseUrlKey, "http://example.org") + } + } +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/AtomicBooleanAdapter.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/AtomicBooleanAdapter.kt new file mode 100644 index 000000000000..0c0d0d00fcfa --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/AtomicBooleanAdapter.kt @@ -0,0 +1,19 @@ +package org.openapitools.client.infrastructure + +import kotlinx.serialization.KSerializer +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 + +object AtomicBooleanAdapter : KSerializer { + 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) +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/AtomicIntegerAdapter.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/AtomicIntegerAdapter.kt new file mode 100644 index 000000000000..0060b2a0f1c3 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/AtomicIntegerAdapter.kt @@ -0,0 +1,19 @@ +package org.openapitools.client.infrastructure + +import kotlinx.serialization.KSerializer +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 + +object AtomicIntegerAdapter : KSerializer { + 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) +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/AtomicLongAdapter.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/AtomicLongAdapter.kt new file mode 100644 index 000000000000..6de80cc56bd5 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/AtomicLongAdapter.kt @@ -0,0 +1,19 @@ +package org.openapitools.client.infrastructure + +import kotlinx.serialization.KSerializer +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 + +object AtomicLongAdapter : KSerializer { + 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) +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/BigDecimalAdapter.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/BigDecimalAdapter.kt new file mode 100644 index 000000000000..86cb9efdd727 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/BigDecimalAdapter.kt @@ -0,0 +1,15 @@ +package org.openapitools.client.infrastructure + +import kotlinx.serialization.KSerializer +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 + +object BigDecimalAdapter : KSerializer { + override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("BigDecimal", PrimitiveKind.STRING) + override fun deserialize(decoder: Decoder): BigDecimal = BigDecimal(decoder.decodeString()) + override fun serialize(encoder: Encoder, value: BigDecimal) = encoder.encodeString(value.toPlainString()) +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/BigIntegerAdapter.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/BigIntegerAdapter.kt new file mode 100644 index 000000000000..136017cb21bc --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/BigIntegerAdapter.kt @@ -0,0 +1,20 @@ +package org.openapitools.client.infrastructure + +import kotlinx.serialization.KSerializer +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 + +object BigIntegerAdapter : KSerializer { + override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("BigInteger", PrimitiveKind.STRING) + override fun deserialize(decoder: Decoder): BigInteger { + return BigInteger(decoder.decodeString()) + } + + override fun serialize(encoder: Encoder, value: BigInteger) { + encoder.encodeString(value.toString()) + } +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/CollectionFormats.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/CollectionFormats.kt new file mode 100644 index 000000000000..7f404da69ea0 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/CollectionFormats.kt @@ -0,0 +1,56 @@ +package org.openapitools.client.infrastructure + +class CollectionFormats { + + open class CSVParams { + + var params: List + + constructor(params: List) { + this.params = params + } + + constructor(vararg params: String) { + this.params = listOf(*params) + } + + override fun toString(): String { + return params.joinToString(",") + } + } + + open class SSVParams : CSVParams { + + constructor(params: List) : super(params) + + constructor(vararg params: String) : super(*params) + + override fun toString(): String { + return params.joinToString(" ") + } + } + + class TSVParams : CSVParams { + + constructor(params: List) : super(params) + + constructor(vararg params: String) : super(*params) + + override fun toString(): String { + return params.joinToString("\t") + } + } + + class PIPESParams : CSVParams { + + constructor(params: List) : super(params) + + constructor(vararg params: String) : super(*params) + + override fun toString(): String { + return params.joinToString("|") + } + } + + class SPACEParams : SSVParams() +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateAdapter.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateAdapter.kt new file mode 100644 index 000000000000..923828ff017b --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateAdapter.kt @@ -0,0 +1,22 @@ +package org.openapitools.client.infrastructure + +import kotlinx.serialization.KSerializer +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.format.DateTimeFormatter + +object LocalDateAdapter : KSerializer { + override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalDate", PrimitiveKind.STRING) + + override fun serialize(encoder: Encoder, value: LocalDate) { + encoder.encodeString(DateTimeFormatter.ISO_LOCAL_DATE.format(value)) + } + + override fun deserialize(decoder: Decoder): LocalDate { + return LocalDate.parse(decoder.decodeString(), DateTimeFormatter.ISO_LOCAL_DATE) + } +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateTimeAdapter.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateTimeAdapter.kt new file mode 100644 index 000000000000..52d73dc0ad03 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/LocalDateTimeAdapter.kt @@ -0,0 +1,22 @@ +package org.openapitools.client.infrastructure + +import kotlinx.serialization.KSerializer +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.format.DateTimeFormatter + +object LocalDateTimeAdapter : KSerializer { + override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalDateTime", PrimitiveKind.STRING) + + override fun serialize(encoder: Encoder, value: LocalDateTime) { + encoder.encodeString(DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(value)) + } + + override fun deserialize(decoder: Decoder): LocalDateTime { + return LocalDateTime.parse(decoder.decodeString(), DateTimeFormatter.ISO_LOCAL_DATE_TIME) + } +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/OffsetDateTimeAdapter.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/OffsetDateTimeAdapter.kt new file mode 100644 index 000000000000..f098b5ed1e15 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/OffsetDateTimeAdapter.kt @@ -0,0 +1,22 @@ +package org.openapitools.client.infrastructure + +import kotlinx.serialization.KSerializer +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.format.DateTimeFormatter + +object OffsetDateTimeAdapter : KSerializer { + override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("OffsetDateTime", PrimitiveKind.STRING) + + override fun serialize(encoder: Encoder, value: OffsetDateTime) { + encoder.encodeString(DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(value)) + } + + override fun deserialize(decoder: Decoder): OffsetDateTime { + return OffsetDateTime.parse(decoder.decodeString(), DateTimeFormatter.ISO_OFFSET_DATE_TIME) + } +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/ResponseExt.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/ResponseExt.kt new file mode 100644 index 000000000000..0f121a95f5be --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/ResponseExt.kt @@ -0,0 +1,4 @@ +package org.openapitools.client.infrastructure + +import retrofit2.Response + diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt new file mode 100644 index 000000000000..1bed97472b3a --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/Serializer.kt @@ -0,0 +1,73 @@ +package org.openapitools.client.infrastructure + +import java.math.BigDecimal +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.json.JsonBuilder +import kotlinx.serialization.modules.SerializersModule +import kotlinx.serialization.modules.SerializersModuleBuilder +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 { + private var isAdaptersInitialized = false + + @JvmStatic + val kotlinxSerializationAdapters: SerializersModule by lazy { + isAdaptersInitialized = true + SerializersModule { + 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) + + apply(kotlinxSerializationAdaptersConfiguration) + } + } + + var kotlinxSerializationAdaptersConfiguration: SerializersModuleBuilder.() -> Unit = {} + set(value) { + check(!isAdaptersInitialized) { + "Cannot configure kotlinxSerializationAdaptersConfiguration after kotlinxSerializationAdapters has been initialized." + } + field = value + } + + private var isJsonInitialized = false + + @JvmStatic + val kotlinxSerializationJson: Json by lazy { + isJsonInitialized = true + Json { + serializersModule = kotlinxSerializationAdapters + encodeDefaults = true + ignoreUnknownKeys = true + isLenient = true + + apply(kotlinxSerializationJsonConfiguration) + } + } + + var kotlinxSerializationJsonConfiguration: JsonBuilder.() -> Unit = {} + set(value) { + check(!isJsonInitialized) { + "Cannot configure kotlinxSerializationJsonConfiguration after kotlinxSerializationJson has been initialized." + } + field = value + } +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/StringBuilderAdapter.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/StringBuilderAdapter.kt new file mode 100644 index 000000000000..b510e73808a5 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/StringBuilderAdapter.kt @@ -0,0 +1,18 @@ +package org.openapitools.client.infrastructure + +import kotlinx.serialization.KSerializer +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 + +object StringBuilderAdapter : KSerializer { + 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) +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/URIAdapter.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/URIAdapter.kt new file mode 100644 index 000000000000..8b4015feddc6 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/URIAdapter.kt @@ -0,0 +1,19 @@ +package org.openapitools.client.infrastructure + +import kotlinx.serialization.KSerializer +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 + +object URIAdapter : KSerializer { + override fun serialize(encoder: Encoder, value: URI) { + encoder.encodeString(value.toASCIIString()) + } + + override fun deserialize(decoder: Decoder): URI = URI(decoder.decodeString()) + + override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("URI", PrimitiveKind.STRING) +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/URLAdapter.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/URLAdapter.kt new file mode 100644 index 000000000000..9aa0326662e7 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/URLAdapter.kt @@ -0,0 +1,19 @@ +package org.openapitools.client.infrastructure + +import kotlinx.serialization.KSerializer +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 + +object URLAdapter : KSerializer { + 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) +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/UUIDAdapter.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/UUIDAdapter.kt new file mode 100644 index 000000000000..64ff2f9139fe --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/infrastructure/UUIDAdapter.kt @@ -0,0 +1,21 @@ +package org.openapitools.client.infrastructure + +import kotlinx.serialization.KSerializer +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 + +object UUIDAdapter : KSerializer { + override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("UUID", PrimitiveKind.STRING) + + override fun serialize(encoder: Encoder, value: UUID) { + encoder.encodeString(value.toString()) + } + + override fun deserialize(decoder: Decoder): UUID { + return UUID.fromString(decoder.decodeString()) + } +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/AnyOfUserOrPet.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/AnyOfUserOrPet.kt new file mode 100644 index 000000000000..f20267693032 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/AnyOfUserOrPet.kt @@ -0,0 +1,93 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + +import org.openapitools.client.models.Pet +import org.openapitools.client.models.User + +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 kotlinx.serialization.SerializationException +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.descriptors.buildClassSerialDescriptor +import kotlinx.serialization.json.JsonDecoder +import kotlinx.serialization.json.JsonEncoder +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.decodeFromJsonElement +import kotlinx.serialization.json.encodeToJsonElement + +/** + * + * + */ +@Serializable(with = AnyOfUserOrPetSerializer::class) + +sealed interface AnyOfUserOrPet { + @JvmInline + value class UserValue(val value: User) : AnyOfUserOrPet + + @JvmInline + value class PetValue(val value: Pet) : AnyOfUserOrPet + +} + +object AnyOfUserOrPetSerializer : KSerializer { + override val descriptor: SerialDescriptor = buildClassSerialDescriptor("AnyOfUserOrPet") + + override fun serialize(encoder: Encoder, value: AnyOfUserOrPet) { + val jsonEncoder = encoder as? JsonEncoder ?: throw SerializationException("AnyOfUserOrPet can only be serialized with Json") + + when (value) { + is AnyOfUserOrPet.UserValue -> jsonEncoder.encodeSerializableValue(User.serializer(), value.value) + is AnyOfUserOrPet.PetValue -> jsonEncoder.encodeSerializableValue(Pet.serializer(), value.value) + } + } + + override fun deserialize(decoder: Decoder): AnyOfUserOrPet { + val jsonDecoder = decoder as? JsonDecoder ?: throw SerializationException("AnyOfUserOrPet can only be deserialized with Json") + val jsonElement = jsonDecoder.decodeJsonElement() + + val errorMessages = mutableListOf() + + if (jsonElement !is JsonPrimitive) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement(jsonElement) + return AnyOfUserOrPet.UserValue(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as User: ${e.message}") + } + } + if (jsonElement !is JsonPrimitive) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement(jsonElement) + return AnyOfUserOrPet.PetValue(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as Pet: ${e.message}") + } + } + + throw SerializationException("Cannot deserialize AnyOfUserOrPet. Tried: ${errorMessages.joinToString(", ")}") + } +} + diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/AnyOfUserOrPetOrArrayString.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/AnyOfUserOrPetOrArrayString.kt new file mode 100644 index 000000000000..af52eab554bf --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/AnyOfUserOrPetOrArrayString.kt @@ -0,0 +1,105 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + +import org.openapitools.client.models.Pet +import org.openapitools.client.models.User + +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 kotlinx.serialization.SerializationException +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.descriptors.buildClassSerialDescriptor +import kotlinx.serialization.json.JsonDecoder +import kotlinx.serialization.json.JsonEncoder +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.decodeFromJsonElement +import kotlinx.serialization.json.encodeToJsonElement + +/** + * + * + */ +@Serializable(with = AnyOfUserOrPetOrArrayStringSerializer::class) + +sealed interface AnyOfUserOrPetOrArrayString { + @JvmInline + value class UserValue(val value: User) : AnyOfUserOrPetOrArrayString + + @JvmInline + value class PetValue(val value: Pet) : AnyOfUserOrPetOrArrayString + + @JvmInline + value class ListStringValue(val value: kotlin.collections.List) : AnyOfUserOrPetOrArrayString + +} + +object AnyOfUserOrPetOrArrayStringSerializer : KSerializer { + override val descriptor: SerialDescriptor = buildClassSerialDescriptor("AnyOfUserOrPetOrArrayString") + + override fun serialize(encoder: Encoder, value: AnyOfUserOrPetOrArrayString) { + val jsonEncoder = encoder as? JsonEncoder ?: throw SerializationException("AnyOfUserOrPetOrArrayString can only be serialized with Json") + + when (value) { + is AnyOfUserOrPetOrArrayString.UserValue -> jsonEncoder.encodeSerializableValue(User.serializer(), value.value) + is AnyOfUserOrPetOrArrayString.PetValue -> jsonEncoder.encodeSerializableValue(Pet.serializer(), value.value) + is AnyOfUserOrPetOrArrayString.ListStringValue -> jsonEncoder.encodeJsonElement(jsonEncoder.json.encodeToJsonElement(value.value)) + } + } + + override fun deserialize(decoder: Decoder): AnyOfUserOrPetOrArrayString { + val jsonDecoder = decoder as? JsonDecoder ?: throw SerializationException("AnyOfUserOrPetOrArrayString can only be deserialized with Json") + val jsonElement = jsonDecoder.decodeJsonElement() + + val errorMessages = mutableListOf() + + if (jsonElement !is JsonPrimitive) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement(jsonElement) + return AnyOfUserOrPetOrArrayString.UserValue(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as User: ${e.message}") + } + } + if (jsonElement !is JsonPrimitive) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement(jsonElement) + return AnyOfUserOrPetOrArrayString.PetValue(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as Pet: ${e.message}") + } + } + if (jsonElement is JsonArray) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement>(jsonElement) + return AnyOfUserOrPetOrArrayString.ListStringValue(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as kotlin.collections.List: ${e.message}") + } + } + + throw SerializationException("Cannot deserialize AnyOfUserOrPetOrArrayString. Tried: ${errorMessages.joinToString(", ")}") + } +} + diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/BooleanOrLong.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/BooleanOrLong.kt new file mode 100644 index 000000000000..630293f1274d --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/BooleanOrLong.kt @@ -0,0 +1,90 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + + +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 kotlinx.serialization.SerializationException +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.descriptors.buildClassSerialDescriptor +import kotlinx.serialization.json.JsonDecoder +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonEncoder +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.decodeFromJsonElement +import kotlinx.serialization.json.encodeToJsonElement + +/** + * + * + */ +@Serializable(with = BooleanOrLongSerializer::class) +sealed interface BooleanOrLong { + @JvmInline + value class BooleanValue(val value: kotlin.Boolean) : BooleanOrLong + + @JvmInline + value class LongValue(val value: kotlin.Long) : BooleanOrLong + +} + +object BooleanOrLongSerializer : KSerializer { + override val descriptor: SerialDescriptor = buildClassSerialDescriptor("BooleanOrLong") + + override fun serialize(encoder: Encoder, value: BooleanOrLong) { + val jsonEncoder = encoder as? JsonEncoder ?: throw SerializationException("BooleanOrLong can only be serialized with Json") + + when (value) { + is BooleanOrLong.BooleanValue -> jsonEncoder.encodeBoolean(value.value) + is BooleanOrLong.LongValue -> jsonEncoder.encodeLong(value.value) + } + } + + override fun deserialize(decoder: Decoder): BooleanOrLong { + val jsonDecoder = decoder as? JsonDecoder ?: throw SerializationException("BooleanOrLong can only be deserialized with Json") + val jsonElement = jsonDecoder.decodeJsonElement() + + val errorMessages = mutableListOf() + + if (jsonElement is JsonPrimitive && !jsonElement.isString) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement(jsonElement) + return BooleanOrLong.BooleanValue(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as kotlin.Boolean: ${e.message}") + } + } + if (jsonElement is JsonPrimitive && !jsonElement.isString) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement(jsonElement) + return BooleanOrLong.LongValue(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as kotlin.Long: ${e.message}") + } + } + + throw SerializationException("Cannot deserialize BooleanOrLong. Tried: ${errorMessages.joinToString(", ")}") + } +} + diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/Pet.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/Pet.kt new file mode 100644 index 000000000000..449d1430d70a --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/Pet.kt @@ -0,0 +1,48 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + + +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 + +/** + * + * + * @param id + * @param name + */ +@Serializable + +data class Pet ( + + @SerialName(value = "id") + val id: kotlin.Long, + + @SerialName(value = "name") + val name: kotlin.String + +) { + + +} + diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/StringOrLong.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/StringOrLong.kt new file mode 100644 index 000000000000..1073f71a25a8 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/StringOrLong.kt @@ -0,0 +1,90 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + + +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 kotlinx.serialization.SerializationException +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.descriptors.buildClassSerialDescriptor +import kotlinx.serialization.json.JsonDecoder +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonEncoder +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.decodeFromJsonElement +import kotlinx.serialization.json.encodeToJsonElement + +/** + * + * + */ +@Serializable(with = StringOrLongSerializer::class) +sealed interface StringOrLong { + @JvmInline + value class StringValue(val value: kotlin.String) : StringOrLong + + @JvmInline + value class LongValue(val value: kotlin.Long) : StringOrLong + +} + +object StringOrLongSerializer : KSerializer { + override val descriptor: SerialDescriptor = buildClassSerialDescriptor("StringOrLong") + + override fun serialize(encoder: Encoder, value: StringOrLong) { + val jsonEncoder = encoder as? JsonEncoder ?: throw SerializationException("StringOrLong can only be serialized with Json") + + when (value) { + is StringOrLong.StringValue -> jsonEncoder.encodeString(value.value) + is StringOrLong.LongValue -> jsonEncoder.encodeLong(value.value) + } + } + + override fun deserialize(decoder: Decoder): StringOrLong { + val jsonDecoder = decoder as? JsonDecoder ?: throw SerializationException("StringOrLong can only be deserialized with Json") + val jsonElement = jsonDecoder.decodeJsonElement() + + val errorMessages = mutableListOf() + + if (jsonElement is JsonPrimitive && jsonElement.isString) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement(jsonElement) + return StringOrLong.StringValue(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as kotlin.String: ${e.message}") + } + } + if (jsonElement is JsonPrimitive && !jsonElement.isString) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement(jsonElement) + return StringOrLong.LongValue(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as kotlin.Long: ${e.message}") + } + } + + throw SerializationException("Cannot deserialize StringOrLong. Tried: ${errorMessages.joinToString(", ")}") + } +} + diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/User.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/User.kt new file mode 100644 index 000000000000..f048a06c2aa9 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/User.kt @@ -0,0 +1,48 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + + +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 + +/** + * + * + * @param id + * @param username + */ +@Serializable + +data class User ( + + @SerialName(value = "id") + val id: kotlin.Long, + + @SerialName(value = "username") + val username: kotlin.String + +) { + + +} + diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/UserOrPet.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/UserOrPet.kt new file mode 100644 index 000000000000..b4b010d17f95 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/UserOrPet.kt @@ -0,0 +1,92 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + +import org.openapitools.client.models.Pet +import org.openapitools.client.models.User + +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 kotlinx.serialization.SerializationException +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.descriptors.buildClassSerialDescriptor +import kotlinx.serialization.json.JsonDecoder +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonEncoder +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.decodeFromJsonElement +import kotlinx.serialization.json.encodeToJsonElement + +/** + * + * + */ +@Serializable(with = UserOrPetSerializer::class) +sealed interface UserOrPet { + @JvmInline + value class UserValue(val value: User) : UserOrPet + + @JvmInline + value class PetValue(val value: Pet) : UserOrPet + +} + +object UserOrPetSerializer : KSerializer { + override val descriptor: SerialDescriptor = buildClassSerialDescriptor("UserOrPet") + + override fun serialize(encoder: Encoder, value: UserOrPet) { + val jsonEncoder = encoder as? JsonEncoder ?: throw SerializationException("UserOrPet can only be serialized with Json") + + when (value) { + is UserOrPet.UserValue -> jsonEncoder.encodeSerializableValue(User.serializer(), value.value) + is UserOrPet.PetValue -> jsonEncoder.encodeSerializableValue(Pet.serializer(), value.value) + } + } + + override fun deserialize(decoder: Decoder): UserOrPet { + val jsonDecoder = decoder as? JsonDecoder ?: throw SerializationException("UserOrPet can only be deserialized with Json") + val jsonElement = jsonDecoder.decodeJsonElement() + + val errorMessages = mutableListOf() + + if (jsonElement !is JsonPrimitive) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement(jsonElement) + return UserOrPet.UserValue(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as User: ${e.message}") + } + } + if (jsonElement !is JsonPrimitive) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement(jsonElement) + return UserOrPet.PetValue(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as Pet: ${e.message}") + } + } + + throw SerializationException("Cannot deserialize UserOrPet. Tried: ${errorMessages.joinToString(", ")}") + } +} + diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/UserOrPetOrArrayString.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/UserOrPetOrArrayString.kt new file mode 100644 index 000000000000..6f8503f59bc7 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/main/kotlin/org/openapitools/client/models/UserOrPetOrArrayString.kt @@ -0,0 +1,104 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + +import org.openapitools.client.models.Pet +import org.openapitools.client.models.User + +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 kotlinx.serialization.SerializationException +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.descriptors.buildClassSerialDescriptor +import kotlinx.serialization.json.JsonDecoder +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonEncoder +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.decodeFromJsonElement +import kotlinx.serialization.json.encodeToJsonElement + +/** + * + * + */ +@Serializable(with = UserOrPetOrArrayStringSerializer::class) +sealed interface UserOrPetOrArrayString { + @JvmInline + value class UserValue(val value: User) : UserOrPetOrArrayString + + @JvmInline + value class PetValue(val value: Pet) : UserOrPetOrArrayString + + @JvmInline + value class ListStringValue(val value: kotlin.collections.List) : UserOrPetOrArrayString + +} + +object UserOrPetOrArrayStringSerializer : KSerializer { + override val descriptor: SerialDescriptor = buildClassSerialDescriptor("UserOrPetOrArrayString") + + override fun serialize(encoder: Encoder, value: UserOrPetOrArrayString) { + val jsonEncoder = encoder as? JsonEncoder ?: throw SerializationException("UserOrPetOrArrayString can only be serialized with Json") + + when (value) { + is UserOrPetOrArrayString.UserValue -> jsonEncoder.encodeSerializableValue(User.serializer(), value.value) + is UserOrPetOrArrayString.PetValue -> jsonEncoder.encodeSerializableValue(Pet.serializer(), value.value) + is UserOrPetOrArrayString.ListStringValue -> jsonEncoder.encodeJsonElement(jsonEncoder.json.encodeToJsonElement(value.value)) + } + } + + override fun deserialize(decoder: Decoder): UserOrPetOrArrayString { + val jsonDecoder = decoder as? JsonDecoder ?: throw SerializationException("UserOrPetOrArrayString can only be deserialized with Json") + val jsonElement = jsonDecoder.decodeJsonElement() + + val errorMessages = mutableListOf() + + if (jsonElement !is JsonPrimitive) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement(jsonElement) + return UserOrPetOrArrayString.UserValue(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as User: ${e.message}") + } + } + if (jsonElement !is JsonPrimitive) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement(jsonElement) + return UserOrPetOrArrayString.PetValue(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as Pet: ${e.message}") + } + } + if (jsonElement is JsonArray) { + try { + val instance = jsonDecoder.json.decodeFromJsonElement>(jsonElement) + return UserOrPetOrArrayString.ListStringValue(instance) + } catch (e: Exception) { + errorMessages.add("Failed to deserialize as kotlin.collections.List: ${e.message}") + } + } + + throw SerializationException("Cannot deserialize UserOrPetOrArrayString. Tried: ${errorMessages.joinToString(", ")}") + } +} + diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/apis/TestApiTest.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/apis/TestApiTest.kt new file mode 100644 index 000000000000..d9843a145fd3 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/apis/TestApiTest.kt @@ -0,0 +1,77 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.apis + +import io.kotlintest.shouldBe +import io.kotlintest.specs.ShouldSpec + +import org.openapitools.client.apis.TestApi +import org.openapitools.client.models.AnyOfUserOrPet +import org.openapitools.client.models.AnyOfUserOrPetOrArrayString +import org.openapitools.client.models.BooleanOrLong +import org.openapitools.client.models.StringOrLong +import org.openapitools.client.models.UserOrPet +import org.openapitools.client.models.UserOrPetOrArrayString + +class TestApiTest : ShouldSpec() { + init { + // uncomment below to create an instance of TestApi + //val apiInstance = TestApi() + + // to test getAnyOf + should("test getAnyOf") { + // uncomment below to test getAnyOf + //val result : AnyOfUserOrPet = apiInstance.getAnyOf() + //result shouldBe ("TODO") + } + + // to test getAnyOfArray + should("test getAnyOfArray") { + // uncomment below to test getAnyOfArray + //val result : AnyOfUserOrPetOrArrayString = apiInstance.getAnyOfArray() + //result shouldBe ("TODO") + } + + // to test getOneOf + should("test getOneOf") { + // uncomment below to test getOneOf + //val result : UserOrPet = apiInstance.getOneOf() + //result shouldBe ("TODO") + } + + // to test getOneOfArray + should("test getOneOfArray") { + // uncomment below to test getOneOfArray + //val result : UserOrPetOrArrayString = apiInstance.getOneOfArray() + //result shouldBe ("TODO") + } + + // to test getOneOfBooleanPrimitive + should("test getOneOfBooleanPrimitive") { + // uncomment below to test getOneOfBooleanPrimitive + //val result : BooleanOrLong = apiInstance.getOneOfBooleanPrimitive() + //result shouldBe ("TODO") + } + + // to test getOneOfPrimitive + should("test getOneOfPrimitive") { + // uncomment below to test getOneOfPrimitive + //val result : StringOrLong = apiInstance.getOneOfPrimitive() + //result shouldBe ("TODO") + } + + } +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/AnyOfUserOrPetOrArrayStringTest.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/AnyOfUserOrPetOrArrayStringTest.kt new file mode 100644 index 000000000000..55540c2798d4 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/AnyOfUserOrPetOrArrayStringTest.kt @@ -0,0 +1,49 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + +import io.kotlintest.shouldBe +import io.kotlintest.specs.ShouldSpec + +import org.openapitools.client.models.AnyOfUserOrPetOrArrayString +import org.openapitools.client.models.Pet +import org.openapitools.client.models.User + +class AnyOfUserOrPetOrArrayStringTest : ShouldSpec() { + init { + // uncomment below to create an instance of AnyOfUserOrPetOrArrayString + //val modelInstance = AnyOfUserOrPetOrArrayString() + + // to test the property `id` + should("test id") { + // uncomment below to test the property + //modelInstance.id shouldBe ("TODO") + } + + // to test the property `username` + should("test username") { + // uncomment below to test the property + //modelInstance.username shouldBe ("TODO") + } + + // to test the property `name` + should("test name") { + // uncomment below to test the property + //modelInstance.name shouldBe ("TODO") + } + + } +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/AnyOfUserOrPetTest.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/AnyOfUserOrPetTest.kt new file mode 100644 index 000000000000..fd72e111c26a --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/AnyOfUserOrPetTest.kt @@ -0,0 +1,49 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + +import io.kotlintest.shouldBe +import io.kotlintest.specs.ShouldSpec + +import org.openapitools.client.models.AnyOfUserOrPet +import org.openapitools.client.models.Pet +import org.openapitools.client.models.User + +class AnyOfUserOrPetTest : ShouldSpec() { + init { + // uncomment below to create an instance of AnyOfUserOrPet + //val modelInstance = AnyOfUserOrPet() + + // to test the property `id` + should("test id") { + // uncomment below to test the property + //modelInstance.id shouldBe ("TODO") + } + + // to test the property `username` + should("test username") { + // uncomment below to test the property + //modelInstance.username shouldBe ("TODO") + } + + // to test the property `name` + should("test name") { + // uncomment below to test the property + //modelInstance.name shouldBe ("TODO") + } + + } +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/BooleanOrLongTest.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/BooleanOrLongTest.kt new file mode 100644 index 000000000000..68c6b42a61cc --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/BooleanOrLongTest.kt @@ -0,0 +1,29 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + +import io.kotlintest.shouldBe +import io.kotlintest.specs.ShouldSpec + +import org.openapitools.client.models.BooleanOrLong + +class BooleanOrLongTest : ShouldSpec() { + init { + // uncomment below to create an instance of BooleanOrLong + //val modelInstance = BooleanOrLong() + + } +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/PetTest.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/PetTest.kt new file mode 100644 index 000000000000..d1e36c1ac8fd --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/PetTest.kt @@ -0,0 +1,41 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + +import io.kotlintest.shouldBe +import io.kotlintest.specs.ShouldSpec + +import org.openapitools.client.models.Pet + +class PetTest : ShouldSpec() { + init { + // uncomment below to create an instance of Pet + //val modelInstance = Pet() + + // to test the property `id` + should("test id") { + // uncomment below to test the property + //modelInstance.id shouldBe ("TODO") + } + + // to test the property `name` + should("test name") { + // uncomment below to test the property + //modelInstance.name shouldBe ("TODO") + } + + } +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/StringOrLongTest.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/StringOrLongTest.kt new file mode 100644 index 000000000000..4fac1bc3eb4a --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/StringOrLongTest.kt @@ -0,0 +1,29 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + +import io.kotlintest.shouldBe +import io.kotlintest.specs.ShouldSpec + +import org.openapitools.client.models.StringOrLong + +class StringOrLongTest : ShouldSpec() { + init { + // uncomment below to create an instance of StringOrLong + //val modelInstance = StringOrLong() + + } +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/UserOrPetOrArrayStringTest.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/UserOrPetOrArrayStringTest.kt new file mode 100644 index 000000000000..e7b2f745b51c --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/UserOrPetOrArrayStringTest.kt @@ -0,0 +1,49 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + +import io.kotlintest.shouldBe +import io.kotlintest.specs.ShouldSpec + +import org.openapitools.client.models.UserOrPetOrArrayString +import org.openapitools.client.models.Pet +import org.openapitools.client.models.User + +class UserOrPetOrArrayStringTest : ShouldSpec() { + init { + // uncomment below to create an instance of UserOrPetOrArrayString + //val modelInstance = UserOrPetOrArrayString() + + // to test the property `id` + should("test id") { + // uncomment below to test the property + //modelInstance.id shouldBe ("TODO") + } + + // to test the property `username` + should("test username") { + // uncomment below to test the property + //modelInstance.username shouldBe ("TODO") + } + + // to test the property `name` + should("test name") { + // uncomment below to test the property + //modelInstance.name shouldBe ("TODO") + } + + } +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/UserOrPetTest.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/UserOrPetTest.kt new file mode 100644 index 000000000000..463c5d666bc9 --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/UserOrPetTest.kt @@ -0,0 +1,49 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + +import io.kotlintest.shouldBe +import io.kotlintest.specs.ShouldSpec + +import org.openapitools.client.models.UserOrPet +import org.openapitools.client.models.Pet +import org.openapitools.client.models.User + +class UserOrPetTest : ShouldSpec() { + init { + // uncomment below to create an instance of UserOrPet + //val modelInstance = UserOrPet() + + // to test the property `id` + should("test id") { + // uncomment below to test the property + //modelInstance.id shouldBe ("TODO") + } + + // to test the property `username` + should("test username") { + // uncomment below to test the property + //modelInstance.username shouldBe ("TODO") + } + + // to test the property `name` + should("test name") { + // uncomment below to test the property + //modelInstance.name shouldBe ("TODO") + } + + } +} diff --git a/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/UserTest.kt b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/UserTest.kt new file mode 100644 index 000000000000..40b69f12dd4a --- /dev/null +++ b/samples/client/others/kotlin-oneOf-anyOf-kotlinx-serialization/src/test/kotlin/org/openapitools/client/models/UserTest.kt @@ -0,0 +1,41 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport" +) + +package org.openapitools.client.models + +import io.kotlintest.shouldBe +import io.kotlintest.specs.ShouldSpec + +import org.openapitools.client.models.User + +class UserTest : ShouldSpec() { + init { + // uncomment below to create an instance of User + //val modelInstance = User() + + // to test the property `id` + should("test id") { + // uncomment below to test the property + //modelInstance.id shouldBe ("TODO") + } + + // to test the property `username` + should("test username") { + // uncomment below to test the property + //modelInstance.username shouldBe ("TODO") + } + + } +} diff --git a/samples/client/petstore/kotlin-model-prefix-type-mappings/src/main/kotlin/org/openapitools/client/models/ApiAnyOfUserOrPet.kt b/samples/client/petstore/kotlin-model-prefix-type-mappings/src/main/kotlin/org/openapitools/client/models/ApiAnyOfUserOrPet.kt index e7c337f2ebd7..bc94ecdcc81d 100644 --- a/samples/client/petstore/kotlin-model-prefix-type-mappings/src/main/kotlin/org/openapitools/client/models/ApiAnyOfUserOrPet.kt +++ b/samples/client/petstore/kotlin-model-prefix-type-mappings/src/main/kotlin/org/openapitools/client/models/ApiAnyOfUserOrPet.kt @@ -36,7 +36,6 @@ import java.io.IOException * */ - data class ApiAnyOfUserOrPet(var actualInstance: Any? = null) { class CustomTypeAdapterFactory : TypeAdapterFactory { @@ -151,3 +150,4 @@ data class ApiAnyOfUserOrPet(var actualInstance: Any? = null) { } } } + diff --git a/samples/client/petstore/kotlin-model-prefix-type-mappings/src/main/kotlin/org/openapitools/client/models/ApiAnyOfUserOrPetOrArrayString.kt b/samples/client/petstore/kotlin-model-prefix-type-mappings/src/main/kotlin/org/openapitools/client/models/ApiAnyOfUserOrPetOrArrayString.kt index 6f349a94b4b8..e935dee1958f 100644 --- a/samples/client/petstore/kotlin-model-prefix-type-mappings/src/main/kotlin/org/openapitools/client/models/ApiAnyOfUserOrPetOrArrayString.kt +++ b/samples/client/petstore/kotlin-model-prefix-type-mappings/src/main/kotlin/org/openapitools/client/models/ApiAnyOfUserOrPetOrArrayString.kt @@ -36,7 +36,6 @@ import java.io.IOException * */ - data class ApiAnyOfUserOrPetOrArrayString(var actualInstance: Any? = null) { class CustomTypeAdapterFactory : TypeAdapterFactory { @@ -202,3 +201,4 @@ data class ApiAnyOfUserOrPetOrArrayString(var actualInstance: Any? = null) { } } } +