Skip to content

Commit ad5dafa

Browse files
committed
feat: nullable types
1 parent 8f0b608 commit ad5dafa

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1812
-19
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoClientExperimentalCodegen.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,31 @@ public void processOpts() {
6666
super.processOpts();
6767
supportingFiles.add(new SupportingFile("utils.mustache", "", "utils.go"));
6868
}
69+
70+
@Override
71+
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
72+
objs = super.postProcessModels(objs);
73+
74+
List<Map<String, Object>> models = (List<Map<String, Object>>) objs.get("models");
75+
for (Map<String, Object> m : models) {
76+
Object v = m.get("model");
77+
if (v instanceof CodegenModel) {
78+
CodegenModel model = (CodegenModel) v;
79+
if (model.isEnum) {
80+
continue;
81+
}
82+
83+
for (CodegenProperty param : model.vars) {
84+
if (!param.isNullable) {
85+
continue;
86+
}
87+
88+
param.dataType = "Nullable" + Character.toUpperCase(param.dataType.charAt(0))
89+
+ param.dataType.substring(1);
90+
}
91+
}
92+
}
93+
94+
return objs;
95+
}
6996
}

modules/openapi-generator/src/main/resources/go-experimental/model.mustache

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{{>partial_header}}
22
package {{packageName}}
3+
34
{{#models}}
4-
{{#imports}}
5-
{{#-first}}
65
import (
7-
{{/-first}}
6+
"bytes"
7+
"encoding/json"
8+
{{#imports}}
89
"{{import}}"
9-
{{#-last}}
10-
)
11-
{{/-last}}
1210
{{/imports}}
11+
)
12+
1313
{{#model}}
1414
{{#isEnum}}
1515
// {{{classname}}} {{#description}}{{{.}}}{{/description}}{{^description}}the model '{{{classname}}}'{{/description}}
@@ -25,6 +25,23 @@ const (
2525
{{/enumVars}}
2626
{{/allowableValues}}
2727
)
28+
29+
type Nullable{{{classname}}} struct {
30+
Value {{{classname}}}
31+
ExplicitNull bool
32+
}
33+
34+
func (v Nullable{{{classname}}}) MarshalJSON() ([]byte, error) {
35+
switch {
36+
case v.ExplicitNull && v.Value:
37+
return nil, ErrInvalidNullable
38+
case v.ExplicitNull:
39+
return []byte("null"), nil
40+
default:
41+
return []byte("{{{value}}}"), nil
42+
}
43+
}
44+
2845
{{/isEnum}}
2946
{{^isEnum}}
3047
// {{classname}}{{#description}} {{{description}}}{{/description}}{{^description}} struct for {{{classname}}}{{/description}}
@@ -35,7 +52,7 @@ type {{classname}} struct {
3552
{{#description}}
3653
// {{{description}}}
3754
{{/description}}
38-
{{name}} {{^required}}{{^isNullable}}*{{/isNullable}}{{/required}}{{{dataType}}} `json:"{{baseName}}{{^required}}{{^isNullable}},omitempty{{/isNullable}}{{/required}}"{{#withXml}} xml:"{{baseName}}{{#isXmlAttribute}},attr{{/isXmlAttribute}}"{{/withXml}}{{#vendorExtensions.x-go-custom-tag}} {{{.}}}{{/vendorExtensions.x-go-custom-tag}}`
55+
{{name}} {{^required}}*{{/required}}{{{dataType}}} `json:"{{baseName}}{{^required}},omitempty{{/required}}"{{#withXml}} xml:"{{baseName}}{{#isXmlAttribute}},attr{{/isXmlAttribute}}"{{/withXml}}{{#vendorExtensions.x-go-custom-tag}} {{{.}}}{{/vendorExtensions.x-go-custom-tag}}`
3956
{{/vars}}
4057
}
4158
{{/isEnum}}
@@ -77,6 +94,29 @@ func (o *{{classname}}) Set{{name}}(v {{dataType}}) {
7794
}
7895
{{/required}}
7996
{{/vars}}
97+
98+
type Nullable{{{classname}}} struct {
99+
Value {{{classname}}}
100+
ExplicitNull bool
101+
}
102+
103+
func (v Nullable{{{classname}}}) MarshalJSON() ([]byte, error) {
104+
switch {
105+
case v.ExplicitNull:
106+
return []byte("null"), nil
107+
default:
108+
return json.Marshal(v.Value)
109+
}
110+
}
111+
112+
func (v *Nullable{{{classname}}}) UnmarshalJSON(src []byte) error {
113+
if bytes.Equal(src, []byte("null")) {
114+
v.ExplicitNull = true
115+
return nil
116+
}
117+
118+
return json.Unmarshal(src, &v.Value)
119+
}
80120
{{/isEnum}}
81121

82122
{{/model}}

modules/openapi-generator/src/main/resources/go-experimental/utils.mustache

Lines changed: 210 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
{{>partial_header}}
22
package {{packageName}}
33

4-
import "time"
4+
import (
5+
"bytes"
6+
"encoding/json"
7+
"errors"
8+
"time"
9+
)
10+
11+
var ErrInvalidNullable = errors.New("nullable cannot have non-zero Value and ExplicitNull simultaneously")
512

613
// PtrBool is a helper routine that returns a pointer to given integer value.
714
func PtrBool(v bool) *bool { return &v }
@@ -15,9 +22,6 @@ func PtrInt32(v int32) *int32 { return &v }
1522
// PtrInt64 is a helper routine that returns a pointer to given integer value.
1623
func PtrInt64(v int64) *int64 { return &v }
1724

18-
// PtrFloat is a helper routine that returns a pointer to given float value.
19-
func PtrFloat(v float32) *float32 { return &v }
20-
2125
// PtrFloat32 is a helper routine that returns a pointer to given float value.
2226
func PtrFloat32(v float32) *float32 { return &v }
2327

@@ -28,4 +32,205 @@ func PtrFloat64(v float64) *float64 { return &v }
2832
func PtrString(v string) *string { return &v }
2933

3034
// PtrTime is helper routine that returns a pointer to given Time value.
31-
func PtrTime(v time.Time) *time.Time { return &v }
35+
func PtrTime(v time.Time) *time.Time { return &v }
36+
37+
type NullableBool struct {
38+
Value bool
39+
ExplicitNull bool
40+
}
41+
42+
func (v NullableBool) MarshalJSON() ([]byte, error) {
43+
switch {
44+
case v.ExplicitNull && v.Value:
45+
return nil, ErrInvalidNullable
46+
case v.ExplicitNull:
47+
return []byte("null"), nil
48+
default:
49+
return json.Marshal(v.Value)
50+
}
51+
}
52+
53+
func (v *NullableBool) UnmarshalJSON(src []byte) error {
54+
if bytes.Equal(src, []byte("null")) {
55+
v.ExplicitNull = true
56+
return nil
57+
}
58+
59+
return json.Unmarshal(src, &v.Value)
60+
}
61+
62+
type NullableInt struct {
63+
Value int
64+
ExplicitNull bool
65+
}
66+
67+
func (v NullableInt) MarshalJSON() ([]byte, error) {
68+
switch {
69+
case v.ExplicitNull && v.Value != 0:
70+
return nil, ErrInvalidNullable
71+
case v.ExplicitNull:
72+
return []byte("null"), nil
73+
default:
74+
return json.Marshal(v.Value)
75+
}
76+
}
77+
78+
79+
func (v *NullableInt) UnmarshalJSON(src []byte) error {
80+
if bytes.Equal(src, []byte("null")) {
81+
v.ExplicitNull = true
82+
return nil
83+
}
84+
85+
return json.Unmarshal(src, &v.Value)
86+
}
87+
88+
type NullableInt32 struct {
89+
Value int32
90+
ExplicitNull bool
91+
}
92+
93+
func (v NullableInt32) MarshalJSON() ([]byte, error) {
94+
switch {
95+
case v.ExplicitNull && v.Value != 0:
96+
return nil, ErrInvalidNullable
97+
case v.ExplicitNull:
98+
return []byte("null"), nil
99+
default:
100+
return json.Marshal(v.Value)
101+
}
102+
}
103+
104+
func (v *NullableInt32) UnmarshalJSON(src []byte) error {
105+
if bytes.Equal(src, []byte("null")) {
106+
v.ExplicitNull = true
107+
return nil
108+
}
109+
110+
return json.Unmarshal(src, &v.Value)
111+
}
112+
113+
type NullableInt64 struct {
114+
Value int64
115+
ExplicitNull bool
116+
}
117+
118+
func (v NullableInt64) MarshalJSON() ([]byte, error) {
119+
switch {
120+
case v.ExplicitNull && v.Value != 0:
121+
return nil, ErrInvalidNullable
122+
case v.ExplicitNull:
123+
return []byte("null"), nil
124+
default:
125+
return json.Marshal(v.Value)
126+
}
127+
}
128+
129+
func (v *NullableInt64) UnmarshalJSON(src []byte) error {
130+
if bytes.Equal(src, []byte("null")) {
131+
v.ExplicitNull = true
132+
return nil
133+
}
134+
135+
return json.Unmarshal(src, &v.Value)
136+
}
137+
138+
type NullableFloat32 struct {
139+
Value float32
140+
ExplicitNull bool
141+
}
142+
143+
func (v NullableFloat32) MarshalJSON() ([]byte, error) {
144+
switch {
145+
case v.ExplicitNull && v.Value != 0.0:
146+
return nil, ErrInvalidNullable
147+
case v.ExplicitNull:
148+
return []byte("null"), nil
149+
default:
150+
return json.Marshal(v.Value)
151+
}
152+
}
153+
154+
func (v *NullableFloat32) UnmarshalJSON(src []byte) error {
155+
if bytes.Equal(src, []byte("null")) {
156+
v.ExplicitNull = true
157+
return nil
158+
}
159+
160+
return json.Unmarshal(src, &v.Value)
161+
}
162+
163+
type NullableFloat64 struct {
164+
Value float64
165+
ExplicitNull bool
166+
}
167+
168+
func (v NullableFloat64) MarshalJSON() ([]byte, error) {
169+
switch {
170+
case v.ExplicitNull && v.Value != 0.0:
171+
return nil, ErrInvalidNullable
172+
case v.ExplicitNull:
173+
return []byte("null"), nil
174+
default:
175+
return json.Marshal(v.Value)
176+
}
177+
}
178+
179+
func (v *NullableFloat64) UnmarshalJSON(src []byte) error {
180+
if bytes.Equal(src, []byte("null")) {
181+
v.ExplicitNull = true
182+
return nil
183+
}
184+
185+
return json.Unmarshal(src, &v.Value)
186+
}
187+
188+
type NullableString struct {
189+
Value string
190+
ExplicitNull bool
191+
}
192+
193+
func (v NullableString) MarshalJSON() ([]byte, error) {
194+
switch {
195+
case v.ExplicitNull && v.Value != "":
196+
return nil, ErrInvalidNullable
197+
case v.ExplicitNull:
198+
return []byte("null"), nil
199+
default:
200+
return json.Marshal(v.Value)
201+
}
202+
}
203+
204+
func (v *NullableString) UnmarshalJSON(src []byte) error {
205+
if bytes.Equal(src, []byte("null")) {
206+
v.ExplicitNull = true
207+
return nil
208+
}
209+
210+
return json.Unmarshal(src, &v.Value)
211+
}
212+
213+
type NullableTime struct {
214+
Value time.Time
215+
ExplicitNull bool
216+
}
217+
218+
func (v NullableTime) MarshalJSON() ([]byte, error) {
219+
switch {
220+
case v.ExplicitNull && !v.Value.IsZero():
221+
return nil, ErrInvalidNullable
222+
case v.ExplicitNull:
223+
return []byte("null"), nil
224+
default:
225+
return v.Value.MarshalJSON()
226+
}
227+
}
228+
229+
func (v *NullableTime) UnmarshalJSON(src []byte) error {
230+
if bytes.Equal(src, []byte("null")) {
231+
v.ExplicitNull = true
232+
return nil
233+
}
234+
235+
return json.Unmarshal(src, &v.Value)
236+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/GIT_USER_ID/GIT_REPO_ID
22

33
require (
4-
github.com/antihax/optional v0.0.0-20180406194304-ca021399b1a6
5-
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a
4+
github.com/antihax/optional v0.0.0-20180406194304-ca021399b1a6
5+
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a
66
)

0 commit comments

Comments
 (0)