Repository: cjbooms/fabrikt
Pull request #118 (2022-03-11 16:20:17)

Map strings with format: uri to java.net.URI
Similar to the UUID handling that has already been added (#57). This matches the behavior of openapi-generator.


Patch:
diff --git a/README.md b/README.md
index a5e8283..249231c 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ The team that built this tool initially contributed to the Kotlin code generatio
 
 It was built at [Zalando Tech](https://opensource.zalando.com/) and is battle-tested in production there. It is particulary well suited to API's built according to Zalando's [REST API guidelines](https://opensource.zalando.com/restful-api-guidelines/). It is [available on Maven Central](https://search.maven.org/artifact/com.cjbooms/fabrikt) at the following coordinates:
 
-```
+```xml
 <dependency>
   <groupId>com.cjbooms</groupId>
   <artifactId>fabrikt</artifactId>
@@ -35,7 +35,7 @@ The library currently has support for generating:
 The test directory forms a living documentation full of [code examples](src/test/resources/examples) generated from different OpenApi3 permutations. 
 
 Below showcases one single example from this directory, which uses an enum discriminator to generate polymorphic sealed classes:
-```
+```yml
 openapi: 3.0.0
 components:
   schemas:
@@ -69,7 +69,7 @@ components:
         - obj_one
         - obj_two
 ```
-```
+```kotlin
 @JsonTypeInfo(
     use = JsonTypeInfo.Id.NAME,
     include = JsonTypeInfo.As.EXISTING_PROPERTY,
diff --git a/src/main/kotlin/com/cjbooms/fabrikt/model/KotlinTypeInfo.kt b/src/main/kotlin/com/cjbooms/fabrikt/model/KotlinTypeInfo.kt
index d2699c1..d33952c 100644
--- a/src/main/kotlin/com/cjbooms/fabrikt/model/KotlinTypeInfo.kt
+++ b/src/main/kotlin/com/cjbooms/fabrikt/model/KotlinTypeInfo.kt
@@ -9,6 +9,7 @@ import com.cjbooms.fabrikt.util.KaizenParserExtensions.toModelClassName
 import com.cjbooms.fabrikt.util.NormalisedString.toModelClassName
 import com.reprezen.kaizen.oasparser.model3.Schema
 import java.math.BigDecimal
+import java.net.URI
 import java.time.LocalDate
 import java.time.OffsetDateTime
 import java.util.UUID
@@ -25,6 +26,7 @@ sealed class KotlinTypeInfo(val modelKClass: KClass<*>, val generatedModelClassN
     object Integer : KotlinTypeInfo(Int::class)
     object BigInt : KotlinTypeInfo(Long::class)
     object Uuid : KotlinTypeInfo(UUID::class)
+    object Uri : KotlinTypeInfo(URI::class)
     object Boolean : KotlinTypeInfo(kotlin.Boolean::class)
     object UntypedObject : KotlinTypeInfo(Any::class)
     object AnyType : KotlinTypeInfo(Any::class)
@@ -57,6 +59,7 @@ sealed class KotlinTypeInfo(val modelKClass: KClass<*>, val generatedModelClassN
                 OasType.Enum ->
                     Enum(schema.getEnumValues(), schema.toModelClassName(enclosingName.toModelClassName()))
                 OasType.Uuid -> Uuid
+                OasType.Uri -> Uri
                 OasType.Double -> Double
                 OasType.Float -> Float
                 OasType.Number -> Numeric
diff --git a/src/main/kotlin/com/cjbooms/fabrikt/model/OasType.kt b/src/main/kotlin/com/cjbooms/fabrikt/model/OasType.kt
index 31ee591..f29738e 100644
--- a/src/main/kotlin/com/cjbooms/fabrikt/model/OasType.kt
+++ b/src/main/kotlin/com/cjbooms/fabrikt/model/OasType.kt
@@ -8,7 +8,7 @@ import com.cjbooms.fabrikt.util.KaizenParserExtensions.isSimpleOneOfAnyDefinitio
 import com.cjbooms.fabrikt.util.KaizenParserExtensions.isTypedAdditionalProperties
 import com.cjbooms.fabrikt.util.KaizenParserExtensions.isUnknownAdditionalProperties
 import com.cjbooms.fabrikt.util.KaizenParserExtensions.isUntypedAdditionalProperties
-import com.cjbooms.fabrikt.util.KaizenParserExtensions.isUuidDefinition
+import com.cjbooms.fabrikt.util.KaizenParserExtensions.isStringDefinitionWithFormat
 import com.cjbooms.fabrikt.util.KaizenParserExtensions.safeType
 import com.reprezen.kaizen.oasparser.model3.Schema
 import kotlin.reflect.KClass
@@ -36,6 +36,7 @@ sealed class OasType(
     object UntypedObject : OasType("object", specialization = Specialization.UNTYPED_OBJECT)
     object Enum : OasType("string", specialization = Specialization.ENUM)
     object Uuid : OasType("string", specialization = Specialization.UUID)
+    object Uri : OasType("string", specialization = Specialization.URI)
     object Map : OasType("object", specialization = Specialization.MAP)
     object UnknownAdditionalProperties :
         OasType("object", specialization = Specialization.UNKNOWN_ADDITIONAL_PROPERTIES)
@@ -68,7 +69,8 @@ sealed class OasType(
 
         private fun Schema.getSpecialization(oasKey: String): Specialization =
             when {
-                isUuidDefinition() -> Specialization.UUID
+                isStringDefinitionWithFormat("uuid") -> Specialization.UUID
+                isStringDefinitionWithFormat("uri") -> Specialization.URI
                 isEnumDefinition() -> Specialization.ENUM
                 isMapTypeAdditionalProperties(oasKey) -> Specialization.TYPED_MAP_ADDITIONAL_PROPERTIES
                 isSimpleMapDefinition() -> Specialization.MAP
@@ -90,6 +92,7 @@ sealed class OasType(
         UNTYPED_OBJECT_ADDITIONAL_PROPERTIES,
         UNTYPED_OBJECT,
         UUID,
+        URI,
         NONE,
         ONE_OF_ANY
     }
diff --git a/src/main/kotlin/com/cjbooms/fabrikt/util/KaizenParserExtensions.kt b/src/main/kotlin/com/cjbooms/fabrikt/util/KaizenParserExtensions.kt
index a684c71..3a6d7b0 100644
--- a/src/main/kotlin/com/cjbooms/fabrikt/util/KaizenParserExtensions.kt
+++ b/src/main/kotlin/com/cjbooms/fabrikt/util/KaizenParserExtensions.kt
@@ -71,8 +71,8 @@ object KaizenParserExtensions {
             )
         )
 
-    fun Schema.isUuidDefinition(): Boolean =
-        this.type == OasType.Text.type && (this.format?.equals("uuid", ignoreCase = true) == true)
+    fun Schema.isStringDefinitionWithFormat(format: String): Boolean =
+        this.type == OasType.Text.type && (this.format?.equals(format, ignoreCase = true) == true)
 
     @Suppress("UNCHECKED_CAST")
     fun Schema.getEnumValues(): List<String> = when {


Test patch:
diff --git a/src/test/resources/examples/githubApi/models/Models.kt b/src/test/resources/examples/githubApi/models/Models.kt
index 2e5536a..995d8b0 100644
--- a/src/test/resources/examples/githubApi/models/Models.kt
+++ b/src/test/resources/examples/githubApi/models/Models.kt
@@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonAnySetter
 import com.fasterxml.jackson.annotation.JsonIgnore
 import com.fasterxml.jackson.annotation.JsonProperty
 import com.fasterxml.jackson.annotation.JsonValue
+import java.net.URI
 import java.time.OffsetDateTime
 import javax.validation.Valid
 import javax.validation.constraints.NotNull
@@ -87,10 +88,10 @@ data class Contributor(
 data class ContributorQueryResult(
     @param:JsonProperty("prev")
     @get:JsonProperty("prev")
-    val prev: String? = null,
+    val prev: URI? = null,
     @param:JsonProperty("next")
     @get:JsonProperty("next")
-    val next: String? = null,
+    val next: URI? = null,
     @param:JsonProperty("items")
     @get:JsonProperty("items")
     @get:NotNull
@@ -223,10 +224,10 @@ data class Organisation(
 data class OrganisationQueryResult(
     @param:JsonProperty("prev")
     @get:JsonProperty("prev")
-    val prev: String? = null,
+    val prev: URI? = null,
     @param:JsonProperty("next")
     @get:JsonProperty("next")
-    val next: String? = null,
+    val next: URI? = null,
     @param:JsonProperty("items")
     @get:JsonProperty("items")
     @get:NotNull
@@ -299,10 +300,10 @@ data class PullRequest(
 data class PullRequestQueryResult(
     @param:JsonProperty("prev")
     @get:JsonProperty("prev")
-    val prev: String? = null,
+    val prev: URI? = null,
     @param:JsonProperty("next")
     @get:JsonProperty("next")
-    val next: String? = null,
+    val next: URI? = null,
     @param:JsonProperty("items")
     @get:JsonProperty("items")
     @get:NotNull
@@ -378,10 +379,10 @@ data class Repository(
 data class RepositoryQueryResult(
     @param:JsonProperty("prev")
     @get:JsonProperty("prev")
-    val prev: String? = null,
+    val prev: URI? = null,
     @param:JsonProperty("next")
     @get:JsonProperty("next")
-    val next: String? = null,
+    val next: URI? = null,
     @param:JsonProperty("items")
     @get:JsonProperty("items")
     @get:NotNull