Skip to content

Commit

Permalink
feat: render patternProperties and additionalProperties as fields for…
Browse files Browse the repository at this point in the history
… Go struct (#301)
  • Loading branch information
jonaslagoni authored Jul 9, 2021
1 parent f05150f commit 8b57c43
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 5 deletions.
6 changes: 6 additions & 0 deletions src/generators/go/GoPreset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<R extends AbstractRenderer, O extends object = any> extends CommonPreset<R, O> {
Expand Down
19 changes: 17 additions & 2 deletions src/generators/go/GoRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -28,6 +30,19 @@ export abstract class GoRenderer extends AbstractRenderer<GoOptions> {
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);
}

Expand Down Expand Up @@ -57,8 +72,8 @@ export abstract class GoRenderer extends AbstractRenderer<GoOptions> {
: fieldName || '';
}

runFieldPreset(fieldName: string, field: CommonModel): Promise<string> {
return this.runPreset('field', { fieldName, field });
runFieldPreset(fieldName: string, field: CommonModel, type: FieldType = FieldType.field): Promise<string> {
return this.runPreset('field', { fieldName, field, type });
}

renderType(model: CommonModel): string {
Expand Down
10 changes: 7 additions & 3 deletions src/generators/go/renderers/StructRenderer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { GoRenderer } from '../GoRenderer';
import { StructPreset } from '../GoPreset';
import { FieldType, StructPreset } from '../GoPreset';

/**
* Renderer for Go's `struct` type
Expand Down Expand Up @@ -27,8 +27,12 @@ export const GO_DEFAULT_STRUCT_PRESET: StructPreset<StructRenderer> = {
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 }`;
},
};
14 changes: 14 additions & 0 deletions test/generators/go/GoGenerator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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);
Expand All @@ -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: [
Expand Down

0 comments on commit 8b57c43

Please sign in to comment.