diff --git a/packages/quicktype-core/src/language/Kotlin/KotlinJacksonRenderer.ts b/packages/quicktype-core/src/language/Kotlin/KotlinJacksonRenderer.ts index 3401ed1fe..c7c9b6532 100644 --- a/packages/quicktype-core/src/language/Kotlin/KotlinJacksonRenderer.ts +++ b/packages/quicktype-core/src/language/Kotlin/KotlinJacksonRenderer.ts @@ -49,6 +49,7 @@ export class KotlinJacksonRenderer extends KotlinRenderer { // and enums in the same union (_enumType) => "is TextNode", (_unionType) => mustNotHappen(), + (_transformedStringType) => "is TextNode", ); } diff --git a/packages/quicktype-core/src/language/Kotlin/KotlinRenderer.ts b/packages/quicktype-core/src/language/Kotlin/KotlinRenderer.ts index 5e1c45b6b..544845b70 100644 --- a/packages/quicktype-core/src/language/Kotlin/KotlinRenderer.ts +++ b/packages/quicktype-core/src/language/Kotlin/KotlinRenderer.ts @@ -1,3 +1,5 @@ +import { iterableSome } from "collection-utils"; + import { anyTypeIssueAnnotation, nullTypeIssueAnnotation, @@ -19,7 +21,7 @@ import { type EnumType, MapType, type ObjectType, - type PrimitiveType, + PrimitiveType, type Type, type UnionType, } from "../../Type"; @@ -158,6 +160,15 @@ export class KotlinRenderer extends ConvenienceRenderer { ]; } + protected haveTransformedStringType( + kind: "date-time" | "date" | "time", + ): boolean { + return iterableSome( + this.typeGraph.allTypesUnordered(), + (t) => t instanceof PrimitiveType && t.kind === kind, + ); + } + protected kotlinType( t: Type, withIssues = false, @@ -194,6 +205,21 @@ export class KotlinRenderer extends ConvenienceRenderer { return [this.kotlinType(nullable, withIssues), optional]; return this.nameForNamedType(unionType); }, + (transformedStringType) => { + if (transformedStringType.kind === "date-time") { + return "OffsetDateTime"; + } + + if (transformedStringType.kind === "date") { + return "LocalDate"; + } + + if (transformedStringType.kind === "time") { + return "OffsetTime"; + } + + return "String"; + }, ); } @@ -211,6 +237,27 @@ export class KotlinRenderer extends ConvenienceRenderer { this.ensureBlankLine(); this.emitLine("package ", this._kotlinOptions.packageName); this.ensureBlankLine(); + + // Check if we need to import java.time classes + const usesDateTime = this.haveTransformedStringType("date-time"); + const usesDate = this.haveTransformedStringType("date"); + const usesTime = this.haveTransformedStringType("time"); + + if (usesDateTime) { + this.emitLine("import java.time.OffsetDateTime"); + } + + if (usesDate) { + this.emitLine("import java.time.LocalDate"); + } + + if (usesTime) { + this.emitLine("import java.time.OffsetTime"); + } + + if (usesDateTime || usesDate || usesTime) { + this.ensureBlankLine(); + } } protected emitTopLevelPrimitive(t: PrimitiveType, name: Name): void { diff --git a/packages/quicktype-core/src/language/Kotlin/language.ts b/packages/quicktype-core/src/language/Kotlin/language.ts index ce72896ac..3b0e03677 100644 --- a/packages/quicktype-core/src/language/Kotlin/language.ts +++ b/packages/quicktype-core/src/language/Kotlin/language.ts @@ -8,6 +8,11 @@ import { import { AcronymStyleOptions, acronymOption } from "../../support/Acronyms"; import { assertNever } from "../../support/Support"; import { TargetLanguage } from "../../TargetLanguage"; +import type { + PrimitiveStringTypeKind, + TransformedStringTypeKind, +} from "../../Type"; +import type { StringTypeMapping } from "../../Type/TypeBuilderUtils"; import type { LanguageName, RendererOptions } from "../../types"; import { KotlinJacksonRenderer } from "./KotlinJacksonRenderer"; @@ -56,6 +61,15 @@ export class KotlinTargetLanguage extends TargetLanguage< return true; } + public get stringTypeMapping(): StringTypeMapping { + const mapping: Map = + new Map(); + mapping.set("date", "date"); + mapping.set("time", "time"); + mapping.set("date-time", "date-time"); + return mapping; + } + protected makeRenderer( renderContext: RenderContext, untypedOptionValues: RendererOptions, diff --git a/test/languages.ts b/test/languages.ts index 9573f3e57..14855564d 100644 --- a/test/languages.ts +++ b/test/languages.ts @@ -1093,7 +1093,7 @@ export const KotlinLanguage: Language = { "76ae1.json", ], allowMissingNull: true, - features: ["enum", "union", "no-defaults"], + features: ["enum", "union", "no-defaults", "date-time"], output: "TopLevel.kt", topLevel: "TopLevel", skipJSON: [ @@ -1178,7 +1178,7 @@ export const KotlinJacksonLanguage: Language = { "76ae1.json", ], allowMissingNull: true, - features: ["enum", "union", "no-defaults"], + features: ["enum", "union", "no-defaults", "date-time"], output: "TopLevel.kt", topLevel: "TopLevel", skipJSON: [