Skip to content

Commit 5f07690

Browse files
special handling for json null type
1 parent df72846 commit 5f07690

File tree

2 files changed

+56
-17
lines changed

2 files changed

+56
-17
lines changed

internal/qmp-gen/templates/alternate

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,21 @@ type {{ $basename }} interface {
2424
{{- range $suffix, $type := .Options }}
2525
{{ $subname := printf "%s%s" $basename $suffix.Go }}
2626

27-
// {{ $subname }} is an implementation of {{ $basename }}
28-
type {{ $subname }} {{ $type.Go }}
27+
{{- if $type.NullType }}
28+
// Special case handling of JSON null type
29+
type is{{ $subname }}Nullable interface {
30+
isNull() bool
31+
}
32+
type {{ $subname }} struct {
33+
isNotNull bool
34+
}
35+
func (n {{ $subname }}) isNull() bool {
36+
return !n.isNotNull
37+
}
38+
{{- else }}
39+
// {{ $subname }} is an implementation of {{ $basename }}
40+
type {{ $subname }} {{ $type.Go }}
41+
{{- end }}
2942

3043
{{- if eq (typeOf (index API $type)) "flatunion" }}
3144
{{ $u := index API $type }}
@@ -38,6 +51,23 @@ type {{ $basename }} interface {
3851
{{- end }}
3952

4053
func decode{{ $basename }}(bs json.RawMessage) ({{ $basename }}, error) {
54+
{{/*
55+
Unfortunately, we have to range through the types three times in order
56+
for us to do the type discovery via unmarshalling in the correct order
57+
*/}}
58+
{{- range $suffix, $type := .Options }}
59+
{{- if $type.NullType }}
60+
// Always try unmarshalling for nil first if it's an option
61+
// because other types could unmarshal successfully in the case
62+
// where a Null json type was provided.
63+
var {{ $suffix }} *int
64+
if err := json.Unmarshal([]byte(bs), &{{ $suffix }}); err == nil {
65+
if {{ $suffix }} == nil {
66+
return {{ printf "%s%s" $basename $suffix.Go }}{}, nil
67+
}
68+
}
69+
{{- end }}
70+
{{- end }}
4171
{{- range $suffix, $type := .Options }}
4272
{{- if $type.SimpleType }}
4373
var {{ $suffix }} {{ printf "%s%s" $basename $suffix.Go }}
@@ -47,22 +77,24 @@ func decode{{ $basename }}(bs json.RawMessage) ({{ $basename }}, error) {
4777
{{- end }}
4878
{{- end }}
4979
{{- range $suffix, $type := .Options }}
50-
{{- if not $type.SimpleType }}
51-
{{ $subtype := index API $type }}
52-
{{- if eq (typeOf $subtype) "flatunion" }}
53-
if {{ $suffix }}, err := decode{{ $type.Go }}([]byte(bs)); err == nil {
54-
switch impl := {{ $suffix }}.(type) {
55-
{{- range $suffix, $type := $subtype.Options }}
56-
case {{ $subtype.Name.Go }}{{ $suffix.Go }}:
57-
return impl, nil
58-
{{- end }}
80+
{{- if not $type.NullType }}
81+
{{- if not $type.SimpleType }}
82+
{{ $subtype := index API $type }}
83+
{{- if eq (typeOf $subtype) "flatunion" }}
84+
if {{ $suffix }}, err := decode{{ $type.Go }}([]byte(bs)); err == nil {
85+
switch impl := {{ $suffix }}.(type) {
86+
{{- range $suffix, $type := $subtype.Options }}
87+
case {{ $subtype.Name.Go }}{{ $suffix.Go }}:
88+
return impl, nil
89+
{{- end }}
90+
}
5991
}
60-
}
61-
{{- else }}
62-
var {{ $suffix }} {{ printf "%s%s" $basename $suffix.Go }}
63-
if err := json.Unmarshal([]byte(bs), &{{ $suffix }}); err == nil {
64-
return {{ $suffix }}, nil
65-
}
92+
{{- else }}
93+
var {{ $suffix }} {{ printf "%s%s" $basename $suffix.Go }}
94+
if err := json.Unmarshal([]byte(bs), &{{ $suffix }}); err == nil {
95+
return {{ $suffix }}, nil
96+
}
97+
{{- end }}
6698
{{- end }}
6799
{{- end }}
68100
{{- end }}

internal/qmp-gen/types.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,13 @@ func (n name) SimpleType() bool {
475475
return ok
476476
}
477477

478+
func (n name) NullType() bool {
479+
if n.SimpleType() {
480+
return false
481+
}
482+
return strings.EqualFold(string(n), "Null")
483+
}
484+
478485
func (n name) InterfaceType(api map[name]interface{}) bool {
479486
if n.SimpleType() {
480487
return false

0 commit comments

Comments
 (0)