From 8b57c4387c443cc6716812a327cd1330508bcbe7 Mon Sep 17 00:00:00 2001 From: Jonas Lagoni Date: Fri, 9 Jul 2021 13:58:22 +0200 Subject: [PATCH] feat: render patternProperties and additionalProperties as fields for Go struct (#301) --- src/generators/go/GoPreset.ts | 6 ++++++ src/generators/go/GoRenderer.ts | 19 +++++++++++++++++-- src/generators/go/renderers/StructRenderer.ts | 10 +++++++--- test/generators/go/GoGenerator.spec.ts | 14 ++++++++++++++ 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/generators/go/GoPreset.ts b/src/generators/go/GoPreset.ts index df05957493..8c48d1c475 100644 --- a/src/generators/go/GoPreset.ts +++ b/src/generators/go/GoPreset.ts @@ -4,9 +4,15 @@ import { Preset, CommonModel, CommonPreset, PresetArgs, EnumPreset } from '../.. import { StructRenderer, GO_DEFAULT_STRUCT_PRESET } from './renderers/StructRenderer'; import { EnumRenderer, GO_DEFAULT_ENUM_PRESET } from './renderers/EnumRenderer'; +export enum FieldType { + field, + additionalProperty, + patternProperties +} export interface FieldArgs { fieldName: string; field: CommonModel; + type: FieldType; } export interface StructPreset extends CommonPreset { diff --git a/src/generators/go/GoRenderer.ts b/src/generators/go/GoRenderer.ts index b5802aa465..417f5f7f86 100644 --- a/src/generators/go/GoRenderer.ts +++ b/src/generators/go/GoRenderer.ts @@ -2,6 +2,8 @@ import { AbstractRenderer } from '../AbstractRenderer'; import { GoGenerator, GoOptions } from './GoGenerator'; import { CommonModel, CommonInputModel, Preset } from '../../models'; import { FormatHelpers } from '../../helpers/FormatHelpers'; +import { DefaultPropertyNames, getUniquePropertyName } from '../../helpers'; +import { FieldType } from './GoPreset'; /** * Common renderer for Go types @@ -28,6 +30,19 @@ export abstract class GoRenderer extends AbstractRenderer { content.push(renderField); } + if (this.model.additionalProperties !== undefined) { + const propertyName = getUniquePropertyName(this.model, DefaultPropertyNames.additionalProperties); + const additionalProperty = await this.runFieldPreset(propertyName, this.model.additionalProperties, FieldType.additionalProperty); + content.push(additionalProperty); + } + + if (this.model.patternProperties !== undefined) { + for (const [pattern, patternModel] of Object.entries(this.model.patternProperties)) { + const propertyName = getUniquePropertyName(this.model, `${pattern}${DefaultPropertyNames.patternProperties}`); + const renderedPatternProperty = await this.runFieldPreset(propertyName, patternModel, FieldType.patternProperties); + content.push(renderedPatternProperty); + } + } return this.renderBlock(content); } @@ -57,8 +72,8 @@ export abstract class GoRenderer extends AbstractRenderer { : fieldName || ''; } - runFieldPreset(fieldName: string, field: CommonModel): Promise { - return this.runPreset('field', { fieldName, field }); + runFieldPreset(fieldName: string, field: CommonModel, type: FieldType = FieldType.field): Promise { + return this.runPreset('field', { fieldName, field, type }); } renderType(model: CommonModel): string { diff --git a/src/generators/go/renderers/StructRenderer.ts b/src/generators/go/renderers/StructRenderer.ts index 7228ab1b4c..e8fb19799e 100644 --- a/src/generators/go/renderers/StructRenderer.ts +++ b/src/generators/go/renderers/StructRenderer.ts @@ -1,5 +1,5 @@ import { GoRenderer } from '../GoRenderer'; -import { StructPreset } from '../GoPreset'; +import { FieldType, StructPreset } from '../GoPreset'; /** * Renderer for Go's `struct` type @@ -27,8 +27,12 @@ export const GO_DEFAULT_STRUCT_PRESET: StructPreset = { self({ renderer }) { return renderer.defaultSelf(); }, - field({ fieldName, field, renderer }) { + field({ fieldName, field, renderer, type }) { fieldName = renderer.nameField(fieldName, field); - return `${ fieldName } ${ renderer.renderType(field)}`; + let fieldType = renderer.renderType(field); + if (type === FieldType.additionalProperty || type === FieldType.patternProperties) { + fieldType = `map[string]${fieldType}`; + } + return `${ fieldName } ${ fieldType }`; }, }; diff --git a/test/generators/go/GoGenerator.spec.ts b/test/generators/go/GoGenerator.spec.ts index 695f9bcd5e..f47a183506 100644 --- a/test/generators/go/GoGenerator.spec.ts +++ b/test/generators/go/GoGenerator.spec.ts @@ -20,6 +20,14 @@ describe('GoGenerator', () => { array_type: { type: 'array', items: { type: 'string' } }, }, required: ['street_name', 'city', 'state', 'house_number', 'array_type'], + additionalProperties: { + type: 'string' + }, + patternProperties: { + '^S(.?*)test&': { + type: 'string' + } + }, }; const expected = `// Address represents a Address model. type Address struct { @@ -31,6 +39,8 @@ type Address struct { Members []interface{} TupleType []interface{} ArrayType []string + AdditionalProperties map[string]string + STestPatternProperties map[string]string }`; const inputModel = await generator.process(doc); @@ -51,11 +61,15 @@ type Address struct { type: 'object', properties: { property: { type: 'string' }, + }, + additionalProperties: { + type: 'string' } }; const expected = `// CustomStruct represents a CustomStruct model. type CustomStruct struct { property string + additionalProperties string }`; generator = new GoGenerator({ presets: [