From 82e18607aa6b264296eddb23e42f463c0c66ed73 Mon Sep 17 00:00:00 2001 From: Marcel Jacek Date: Tue, 15 Apr 2025 17:33:58 +0200 Subject: [PATCH] fix: generator does not generate enum code correct - enums which aren't definied in a ref within the API spec, were handled like normal strings --- templates/go/model_simple.mustache | 137 +++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/templates/go/model_simple.mustache b/templates/go/model_simple.mustache index 28709a9..fde8838 100644 --- a/templates/go/model_simple.mustache +++ b/templates/go/model_simple.mustache @@ -277,6 +277,137 @@ func set{{classname}}{{getter}}AttributeType(arg *{{classname}}{{getter}}Attribu {{/isDate}} {{#isEnumRef}} {{! special handling for enums}} +{{#isEnum}} +//isEnum + +// {{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}} {{{description}}}{{^description}}the model '{{{classname}}}'{{/description}} +type {{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}} {{dataType}} + +// List of {{name}} +const ( + {{#allowableValues}} + {{#enumVars}} + {{^-first}} + {{/-first}} + {{! Tweak to get the name in the correct format. Name can not directly passed like in the type, because it would use the enum name }} + {{{classname.toUpperCase}}}{{{enumName}}}_{{name}} {{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}} = {{{value}}} + {{/enumVars}} + {{/allowableValues}} +) + +// All allowed values of {{{classname}}} enum +var Allowed{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}EnumValues = []{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}{ + {{#allowableValues}} + {{#enumVars}} + {{{value}}}, + {{/enumVars}} + {{/allowableValues}} +} + +func (v *{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}) UnmarshalJSON(src []byte) error { + var value {{dataType}} + err := json.Unmarshal(src, &value) + if err != nil { + return err + } + // Allow unmarshalling zero value for testing purposes + var zeroValue {{dataType}} + if value == zeroValue { + return nil + } + enumTypeValue := {{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}(value) + for _, existing := range Allowed{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}EnumValues { + if existing == enumTypeValue { + *v = enumTypeValue + return nil + } + } + + return fmt.Errorf("%+v is not a valid {{classname}}", value) +} + +// New{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}FromValue returns a pointer to a valid {{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}} +// for the value passed as argument, or an error if the value passed is not allowed by the enum +func New{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}FromValue(v {{dataType}}) (*{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}, error) { + ev := {{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}(v) + if ev.IsValid() { + return &ev, nil + } else { + return nil, fmt.Errorf("invalid value '%v' for {{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}: valid values are %v", v, Allowed{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}EnumValues) + } +} + +// IsValid return true if the value is valid for the enum, false otherwise +func (v {{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}) IsValid() bool { + for _, existing := range Allowed{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}EnumValues { + if existing == v { + return true + } + } + return false +} + +// Ptr returns reference to {{{name}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}} value +func (v {{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}) Ptr() *{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}} { + return &v +} + +type Nullable{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}} struct { + value *{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}} + isSet bool +} + +func (v Nullable{{classname}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}) Get() *{{classname}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}} { + return v.value +} + +func (v *Nullable{{classname}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}) Set(val *{{classname}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}) { + v.value = val + v.isSet = true +} + +func (v Nullable{{classname}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}) IsSet() bool { + return v.isSet +} + +func (v *Nullable{{classname}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullable{{classname}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}(val *{{classname}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}) *Nullable{{classname}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}} { + return &Nullable{{classname}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}{value: val, isSet: true} +} + +func (v Nullable{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *Nullable{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}}) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type {{classname}}{{getter}}AttributeType = *{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}} +type {{classname}}{{getter}}ArgType = {{#isNullable}}*{{/isNullable}}{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}} +type {{classname}}{{getter}}RetType = {{#isNullable}}*{{/isNullable}}{{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}} +func get{{classname}}{{getter}}AttributeTypeOk(arg {{classname}}{{getter}}AttributeType) (ret {{classname}}{{getter}}RetType, ok bool) { + if arg == nil { + {{#isNullable}} + return nil,false + {{/isNullable}} + {{^isNullable}} + return ret,false + {{/isNullable}} + } + return {{^isNullable}}*{{/isNullable}}arg,true +} + +func set{{classname}}{{getter}}AttributeType(arg *{{classname}}{{getter}}AttributeType, val {{classname}}{{getter}}RetType) { + *arg={{^isNullable}}&{{/isNullable}}val +} +{{/isEnum}} +{{^isEnum}} // isEnumRef type {{classname}}{{getter}}AttributeType = *{{^isNumeric}}{{dataType}}{{/isNumeric}}{{#isNumeric}}int64{{/isNumeric}} type {{classname}}{{getter}}ArgType = {{#isNullable}}*{{/isNullable}}{{^isNumeric}}{{dataType}}{{/isNumeric}}{{#isNumeric}}int64{{/isNumeric}} @@ -296,6 +427,7 @@ func get{{classname}}{{getter}}AttributeTypeOk(arg {{classname}}{{getter}}Attrib func set{{classname}}{{getter}}AttributeType(arg *{{classname}}{{getter}}AttributeType, val {{classname}}{{getter}}RetType) { *arg={{^isNullable}}&{{/isNullable}}val } +{{/isEnum}} {{/isEnumRef}} {{#isModel}} {{! special handling for recursive datatypes}} @@ -542,8 +674,13 @@ func New{{classname}}WithDefaults() *{{classname}} { {{#defaultValue}} {{^vendorExtensions.x-golang-is-container}} {{^isReadOnly}} +{{#isEnum}} + var {{nameInCamelCase}} {{{classname}}}{{#lambda.titlecase}}{{nameInCamelCase}}{{/lambda.titlecase}} = {{{.}}} +{{/isEnum}} +{{^isEnum}} {{!we use datatypeWithEnum here, since it will represent the non-nullable name of the datatype, e.g. int64 for NullableInt64}} var {{nameInCamelCase}} {{#isInteger}}int64{{/isInteger}}{{#isNumber}}float64{{/isNumber}}{{^isNumber}}{{^isInteger}}{{dataType}}{{/isInteger}}{{/isNumber}} = {{{.}}} +{{/isEnum}} {{#isNullable}} this.{{name}} = *New{{dataType}}(&{{nameInCamelCase}}) {{/isNullable}}