Support default values from OpenAPI spec in generated models

This commit is contained in:
Niels van Velzen 2022-08-06 22:12:02 +02:00 committed by Max Rumpf
parent 3003a3a592
commit 0b69e2aaf5
5 changed files with 63 additions and 28 deletions

View File

@ -5,19 +5,18 @@ import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.MemberName
import com.squareup.kotlinpoet.ParameterSpec
import com.squareup.kotlinpoet.ParameterizedTypeName
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.plusParameter
import com.squareup.kotlinpoet.buildCodeBlock
import org.jellyfin.openapi.builder.Builder
import org.jellyfin.openapi.builder.extra.DeprecatedAnnotationSpecBuilder
import org.jellyfin.openapi.builder.extra.DescriptionBuilder
import org.jellyfin.openapi.builder.extra.defaultValue
import org.jellyfin.openapi.constants.Classes
import org.jellyfin.openapi.constants.Packages
import org.jellyfin.openapi.constants.Strings
import org.jellyfin.openapi.constants.Types
import org.jellyfin.openapi.model.ApiServiceOperation
import org.jellyfin.openapi.model.ApiServiceOperationParameter
import org.jellyfin.openapi.model.CustomDefaultValue
import org.jellyfin.openapi.model.IntRangeValidation
import org.jellyfin.openapi.model.ParameterValidation
@ -44,30 +43,7 @@ open class OperationBuilder(
protected fun buildParameter(
data: ApiServiceOperationParameter,
) = ParameterSpec.builder(data.name, data.type).apply {
// Determine class name without parameters
val typeClassName = when (data.type) {
is ClassName -> data.type
is ParameterizedTypeName -> data.type.rawType
else -> null
}
// Set default value
when (data.defaultValue) {
is String -> defaultValue("%S", data.defaultValue)
is Int -> defaultValue("%L", data.defaultValue)
is Boolean -> defaultValue("%L", data.defaultValue)
is CustomDefaultValue -> defaultValue(data.defaultValue.build())
// Set value to null by default for nullable values
null -> when {
typeClassName == Types.COLLECTION ->
defaultValue("%M()", MemberName("kotlin.collections", "emptyList"))
typeClassName == Types.LIST ->
defaultValue("%M()", MemberName("kotlin.collections", "emptyList"))
typeClassName == Types.MAP ->
defaultValue("%M()", MemberName("kotlin.collections", "emptyMap"))
data.type.isNullable -> defaultValue("%L", "null")
}
}
defaultValue(data)
// Add description
descriptionBuilder.build(data.description)?.let {

View File

@ -0,0 +1,57 @@
package org.jellyfin.openapi.builder.extra
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.MemberName
import com.squareup.kotlinpoet.ParameterSpec
import com.squareup.kotlinpoet.ParameterizedTypeName
import com.squareup.kotlinpoet.TypeName
import org.jellyfin.openapi.constants.Types
import org.jellyfin.openapi.model.ApiServiceOperationParameter
import org.jellyfin.openapi.model.CustomDefaultValue
import org.jellyfin.openapi.model.ObjectApiModelProperty
fun ParameterSpec.Builder.defaultValue(
type: TypeName,
defaultValue: Any?,
allowEmptyCollection: Boolean,
) {
// Determine class name without parameters
val typeClassName = when (type) {
is ClassName -> type
is ParameterizedTypeName -> type.rawType
else -> null
}
// Set default value
when (defaultValue) {
is String -> defaultValue("%S", defaultValue)
is Int -> defaultValue("%L", defaultValue)
is Boolean -> defaultValue("%L", defaultValue)
is CustomDefaultValue -> defaultValue(defaultValue.build())
// Set value to null by default for nullable values
null -> when {
typeClassName == Types.COLLECTION && allowEmptyCollection ->
defaultValue("%M()", MemberName("kotlin.collections", "emptyList"))
typeClassName == Types.LIST && allowEmptyCollection ->
defaultValue("%M()", MemberName("kotlin.collections", "emptyList"))
typeClassName == Types.MAP && allowEmptyCollection ->
defaultValue("%M()", MemberName("kotlin.collections", "emptyMap"))
type.isNullable -> defaultValue("%L", "null")
}
}
}
fun ParameterSpec.Builder.defaultValue(parameter: ApiServiceOperationParameter) = defaultValue(
type = parameter.type,
defaultValue = parameter.defaultValue,
allowEmptyCollection = true,
)
fun ParameterSpec.Builder.defaultValue(property: ObjectApiModelProperty) = defaultValue(
type = property.type,
defaultValue = property.defaultValue,
allowEmptyCollection = false,
)

View File

@ -13,6 +13,7 @@ import org.jellyfin.openapi.builder.Builder
import org.jellyfin.openapi.builder.extra.DeprecatedAnnotationSpecBuilder
import org.jellyfin.openapi.builder.extra.DescriptionBuilder
import org.jellyfin.openapi.builder.extra.TypeSerializerBuilder
import org.jellyfin.openapi.builder.extra.defaultValue
import org.jellyfin.openapi.constants.Packages
import org.jellyfin.openapi.constants.Strings
import org.jellyfin.openapi.constants.Types
@ -32,8 +33,7 @@ class ObjectModelBuilder(
data.properties.forEach { property ->
// Create constructor parameter
addParameter(ParameterSpec.builder(property.name, property.type).apply {
// Set value to null by default for nullable values
if (property.type.isNullable) defaultValue("%L", "null")
defaultValue(property)
}.build())
// Create class property

View File

@ -36,6 +36,7 @@ class OpenApiModelBuilder(
ObjectApiModelProperty(
name = name,
originalName = originalName,
defaultValue = property.default,
type = openApiTypeBuilder.build(ModelTypePath(data.name, name), property),
description = property.description,
deprecated = property.deprecated == true

View File

@ -5,6 +5,7 @@ import com.squareup.kotlinpoet.TypeName
data class ObjectApiModelProperty(
val name: String,
val originalName: String,
val defaultValue: Any?,
val type: TypeName,
val description: String?,
val deprecated: Boolean