Replace TextCase class with kasechange library

This commit is contained in:
Niels van Velzen 2020-10-02 21:24:21 +02:00
parent 3b9fd437f0
commit 7599ce989c
10 changed files with 28 additions and 72 deletions

View File

@ -60,6 +60,7 @@ object Dependencies {
const val androidBuildTools = "com.android.tools.build:gradle:4.0.1"
const val swaggerParser = "io.swagger.parser.v3:swagger-parser:2.0.19"
const val kotlinPoet = "com.squareup:kotlinpoet:1.6.0"
const val kasechange = "net.pearx.kasechange:kasechange:1.3.0"
}
/**

View File

@ -13,6 +13,9 @@ dependencies {
// Reading OpenAPI
implementation(Dependencies.swaggerParser)
// Capitalization helper
implementation(Dependencies.kasechange)
// Kotlin code generation
implementation(Dependencies.kotlinPoet)

View File

@ -1,7 +1,8 @@
package org.jellyfin.openapi.builder.api
import net.pearx.kasechange.CaseFormat
import net.pearx.kasechange.toPascalCase
import org.jellyfin.openapi.builder.Builder
import org.jellyfin.openapi.util.asPascalCase
/**
* Converts strings to API service names.
@ -12,5 +13,5 @@ import org.jellyfin.openapi.util.asPascalCase
* helloWorld -> HelloWorldApi
*/
class ApiNameBuilder : Builder<String, String> {
override fun build(data: String) = "${data.asPascalCase().toPascalCase()}Api"
override fun build(data: String) = "${data.toPascalCase(from = CaseFormat.CAPITALIZED_CAMEL)}Api"
}

View File

@ -3,19 +3,20 @@ package org.jellyfin.openapi.builder.model
import com.squareup.kotlinpoet.TypeSpec
import com.squareup.kotlinpoet.asTypeName
import kotlinx.serialization.Serializable
import net.pearx.kasechange.CaseFormat
import net.pearx.kasechange.toPascalCase
import org.jellyfin.openapi.builder.Builder
import org.jellyfin.openapi.builder.extra.DeprecatedAnnotationSpecBuilder
import org.jellyfin.openapi.constants.Packages
import org.jellyfin.openapi.constants.Strings
import org.jellyfin.openapi.model.EmptyApiModel
import org.jellyfin.openapi.model.JellyFile
import org.jellyfin.openapi.util.asPascalCase
class EmptyModelBuilder(
private val deprecatedAnnotationSpecBuilder: DeprecatedAnnotationSpecBuilder
) : Builder<EmptyApiModel, JellyFile> {
override fun build(data: EmptyApiModel): JellyFile {
return TypeSpec.classBuilder(data.name.asPascalCase().toPascalCase())
return TypeSpec.classBuilder(data.name.toPascalCase(from = CaseFormat.CAPITALIZED_CAMEL))
.apply {
data.description?.let { addKdoc(it) }
if (data.deprecated) addAnnotation(deprecatedAnnotationSpecBuilder.build(Strings.DEPRECATED_CLASS))

View File

@ -5,22 +5,24 @@ import com.squareup.kotlinpoet.TypeSpec
import com.squareup.kotlinpoet.asTypeName
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import net.pearx.kasechange.CaseFormat
import net.pearx.kasechange.toPascalCase
import net.pearx.kasechange.toScreamingSnakeCase
import org.jellyfin.openapi.builder.Builder
import org.jellyfin.openapi.builder.extra.DeprecatedAnnotationSpecBuilder
import org.jellyfin.openapi.constants.Packages
import org.jellyfin.openapi.constants.Strings
import org.jellyfin.openapi.model.EnumApiModel
import org.jellyfin.openapi.model.JellyFile
import org.jellyfin.openapi.util.asPascalCase
class EnumModelBuilder(
private val deprecatedAnnotationSpecBuilder: DeprecatedAnnotationSpecBuilder
) : Builder<EnumApiModel, JellyFile> {
override fun build(data: EnumApiModel): JellyFile {
return TypeSpec.enumBuilder(data.name.asPascalCase().toPascalCase())
return TypeSpec.enumBuilder(data.name.toPascalCase(from = CaseFormat.CAPITALIZED_CAMEL))
.apply {
data.constants.forEach {
addEnumConstant(it.asPascalCase().toScreamingSnakeCase(), TypeSpec.anonymousClassBuilder().apply {
addEnumConstant(it.toScreamingSnakeCase(from = CaseFormat.CAPITALIZED_CAMEL), TypeSpec.anonymousClassBuilder().apply {
addAnnotation(AnnotationSpec.builder(SerialName::class).addMember("%S", it).build())
}.build())
}

View File

@ -4,6 +4,8 @@ import com.squareup.kotlinpoet.*
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers
import net.pearx.kasechange.CaseFormat
import net.pearx.kasechange.toPascalCase
import org.jellyfin.openapi.builder.Builder
import org.jellyfin.openapi.builder.extra.DeprecatedAnnotationSpecBuilder
import org.jellyfin.openapi.builder.extra.TypeSerializerBuilder
@ -11,7 +13,6 @@ import org.jellyfin.openapi.constants.Packages
import org.jellyfin.openapi.constants.Strings
import org.jellyfin.openapi.model.JellyFile
import org.jellyfin.openapi.model.ObjectApiModel
import org.jellyfin.openapi.util.asPascalCase
class ObjectModelBuilder(
private val deprecatedAnnotationSpecBuilder: DeprecatedAnnotationSpecBuilder,
@ -63,7 +64,7 @@ class ObjectModelBuilder(
?: emptySet()
// Create class
return TypeSpec.classBuilder(data.name.asPascalCase().toPascalCase())
return TypeSpec.classBuilder(data.name.toPascalCase(from = CaseFormat.CAPITALIZED_CAMEL))
.apply {
modifiers += KModifier.DATA
data.description?.let { addKdoc(it) }

View File

@ -3,6 +3,8 @@ package org.jellyfin.openapi.builder.openapi
import com.squareup.kotlinpoet.asTypeName
import io.swagger.v3.oas.models.PathItem
import io.swagger.v3.oas.models.Paths
import net.pearx.kasechange.CaseFormat
import net.pearx.kasechange.toCamelCase
import org.jellyfin.openapi.builder.Builder
import org.jellyfin.openapi.builder.api.ApiNameBuilder
import org.jellyfin.openapi.constants.MimeType
@ -12,7 +14,6 @@ import org.jellyfin.openapi.model.ApiService
import org.jellyfin.openapi.model.ApiServiceOperation
import org.jellyfin.openapi.model.ApiServiceOperationParameter
import org.jellyfin.openapi.model.HttpMethod
import org.jellyfin.openapi.util.asPascalCase
class OpenApiApiServicesBuilder(
private val apiNameBuilder: ApiNameBuilder,
@ -34,13 +35,13 @@ class OpenApiApiServicesBuilder(
val serviceName = apiNameBuilder.build(operation.tags.firstOrNull()
?: Strings.DEFAULT_API_SERVICE)
if (serviceName !in operations) operations[serviceName] = mutableSetOf()
val operationName = operation.operationId.asPascalCase().toCamelCase()
val operationName = operation.operationId.toCamelCase(from = CaseFormat.CAPITALIZED_CAMEL)
val pathParameters = mutableListOf<ApiServiceOperationParameter>()
val queryParameters = mutableListOf<ApiServiceOperationParameter>()
operation.parameters?.forEach { parameterSpec ->
val parameterName = parameterSpec.name.asPascalCase().toCamelCase()
val parameterName = parameterSpec.name.toCamelCase(from = CaseFormat.CAPITALIZED_CAMEL)
val type = openApiTypeBuilder.build(ApiTypePath(serviceName, operationName, parameterName), parameterSpec.schema)
when (parameterSpec.`in`) {

View File

@ -1,11 +1,12 @@
package org.jellyfin.openapi.builder.openapi
import io.swagger.v3.oas.models.media.Schema
import net.pearx.kasechange.CaseFormat
import net.pearx.kasechange.toCamelCase
import org.jellyfin.openapi.builder.Builder
import org.jellyfin.openapi.builder.model.ModelBuilder
import org.jellyfin.openapi.hooks.ModelTypePath
import org.jellyfin.openapi.model.*
import org.jellyfin.openapi.util.asPascalCase
class OpenApiModelBuilder(
private val openApiTypeBuilder: OpenApiTypeBuilder,
@ -19,7 +20,7 @@ class OpenApiModelBuilder(
true -> EmptyApiModel(data.name, data.description, data.deprecated == true)
// Otherwise use the object model
false -> ObjectApiModel(data.name, data.description, data.deprecated == true, data.properties.map { (originalName, property) ->
val name = originalName.asPascalCase().toCamelCase()
val name = originalName.toCamelCase(from = CaseFormat.CAPITALIZED_CAMEL)
ObjectApiModelProperty(
name = name,
originalName = originalName,

View File

@ -5,10 +5,11 @@ import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.plusParameter
import com.squareup.kotlinpoet.TypeName
import com.squareup.kotlinpoet.asTypeName
import io.swagger.v3.oas.models.media.*
import net.pearx.kasechange.CaseFormat
import net.pearx.kasechange.toPascalCase
import org.jellyfin.openapi.constants.Packages
import org.jellyfin.openapi.hooks.TypeBuilderHook
import org.jellyfin.openapi.hooks.TypePath
import org.jellyfin.openapi.util.asPascalCase
import java.io.InputStream
import java.time.LocalDateTime
import java.util.*
@ -81,8 +82,7 @@ class OpenApiTypeBuilder(
Packages.MODEL,
reference
.removePrefix("#/components/schemas/")
.asPascalCase()
.toPascalCase()
.toPascalCase(from = CaseFormat.CAPITALIZED_CAMEL)
)
fun buildBinary() = InputStream::class.asTypeName()

View File

@ -1,55 +0,0 @@
package org.jellyfin.openapi.util
/**
* Utility class to convert strings to various standards of text casing
*
* @param parts Individual words that make up a single string
*/
class TextCase(
val parts: List<String>
) {
/**
* @return camelCase
*/
fun toCamelCase(): String = parts.mapIndexed { i, it ->
val lowercase = it.toLowerCase()
// First word should be fully lowercase
if (i > 0) lowercase.capitalize()
else lowercase
}.joinToString(separator = "")
/**
* @return PascalCase
*/
fun toPascalCase(): String = parts.mapIndexed { _, it ->
it.toLowerCase().capitalize()
}.joinToString(separator = "")
/**
* @return SCREAMING_SNAKE_CASE
*/
fun toScreamingSnakeCase(): String = parts.joinToString(separator = "_") {
it.toUpperCase()
}
override fun toString() = parts.toString()
companion object {
/**
* Interpret this string as PascalCase
* @param string PascalCase
*/
fun fromPascalCase(string: String): TextCase {
val regex = "(?<=[A-Z])(?=[A-Z][a-z])|(?<=[^A-Z])(?=[A-Z])|(?<=[A-Za-z])(?=[^A-Za-z])".toRegex()
val parts = regex.split(string)
return TextCase(parts)
}
}
}
/**
* Interpret this string as PascalCase
*/
fun String.asPascalCase(): TextCase = TextCase.fromPascalCase(this)