Skip to content

Commit 7452ece

Browse files
authored
Merge pull request digitalocean#130 from danderson/master
internal/qmp-gen: generate implementations for the commands.
2 parents 8eb38f2 + ac09b90 commit 7452ece

File tree

5 files changed

+3948
-157
lines changed

5 files changed

+3948
-157
lines changed

internal/qmp-gen/generate.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ func renderAPI(templateDir string, api, need map[name]interface{}) ([]byte, erro
150150
return b.String(), err
151151
},
152152
"abort": func(s string) (string, error) { return "", errors.New(s) },
153+
"last": func(fs fields, i int) bool { return i == len(fs)-1 },
153154
})
154155
tmpl, err := tmpl.ParseGlob(filepath.Join(templateDir, "*"))
155156
if err != nil {

internal/qmp-gen/parse_test.go

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,34 @@ type StatusInfo struct {
150150
Status RunState 'json:"status"'
151151
}
152152
153-
// COMMAND query-status
154-
`),
153+
// query-status -> QueryStatus (command)
154+
155+
// QueryStatus implements the "query-status" QMP API call.
156+
func (m *Monitor) QueryStatus() (ret StatusInfo, err error) {
157+
cmd := struct {
158+
}{}
159+
bs, err := json.Marshal(map[string]interface{}{
160+
"execute": "query-status",
161+
"arguments": cmd,
162+
})
163+
if err != nil {
164+
return
165+
}
166+
bs, err = m.mon.Run(bs)
167+
if err != nil {
168+
return
169+
}
170+
res := struct {
171+
Res json.RawMessage 'json:"return"'
172+
}{}
173+
if err = json.Unmarshal(bs, &res); err != nil {
174+
return
175+
}
176+
if err = json.Unmarshal([]byte(res.Res), &ret); err != nil {
177+
return
178+
}
179+
return
180+
}`),
155181
},
156182
}
157183

internal/qmp-gen/templates/command

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,92 @@
1-
// COMMAND {{ .Name }}
1+
// {{ .Name }} -> {{ .Name.Go }} (command)
2+
3+
{{ define "funcArg" -}}
4+
{{- if .List -}}
5+
{{ unexport .Name.FieldName }} []{{ .Type.Go }}
6+
{{- else if and .Optional (not (.Type.InterfaceType API)) -}}
7+
{{ unexport .Name.FieldName }} *{{ .Type.Go }}
8+
{{- else -}}
9+
{{ unexport .Name.FieldName }} {{ .Type.Go }}
10+
{{- end -}}
11+
{{- end }}
12+
13+
{{ define "funcArgs" -}}
14+
{{- if .BoxedInput -}}
15+
cmd *{{ .Inputs.Ref.Go }}
16+
{{- else -}}
17+
{{- $inputs := .Inputs.Fields API -}}
18+
{{- range $i, $f := $inputs -}}
19+
{{- template "funcArg" $f -}}
20+
{{- if not (last $inputs $i) -}},{{- end -}}
21+
{{- end -}}
22+
{{- end -}}
23+
{{- end }}
24+
25+
{{ define "retVal" -}}
26+
{{- if eq .Type "" -}}
27+
(err error)
28+
{{- else if .List -}}
29+
(ret []{{ .Type.Go }}, err error)
30+
{{- else if and .Optional (not (.Type.InterfaceType API)) -}}
31+
(ret *{{ .Type.Go }}, err error)
32+
{{- else -}}
33+
(ret {{ .Type.Go }}, err error)
34+
{{- end -}}
35+
{{- end }}
36+
37+
// {{ .Name.Go }} implements the "{{ .Name }}" QMP API call.
38+
func (m *Monitor) {{ .Name.Go }}({{ template "funcArgs" . }}) {{ template "retVal" .Output }} {
39+
{{- if not .BoxedInput }}
40+
cmd := struct{
41+
{{- range .Inputs.Fields API }}
42+
{{ render . }}
43+
{{- end }}
44+
}{
45+
{{- range .Inputs.Fields API }}
46+
{{ unexport .Name.FieldName }},
47+
{{- end }}
48+
}
49+
{{- end }}
50+
bs, err := json.Marshal(map[string]interface{}{
51+
"execute": "{{ .Name }}",
52+
"arguments": cmd,
53+
})
54+
if err != nil {
55+
return
56+
}
57+
bs, err = m.mon.Run(bs)
58+
if err != nil {
59+
return
60+
}
61+
62+
{{- if ne .Output.Type "" }}
63+
res := struct{
64+
Res json.RawMessage `json:"return"`
65+
}{}
66+
if err = json.Unmarshal(bs, &res); err != nil {
67+
return
68+
}
69+
{{- if .Output.Type.InterfaceType API }}
70+
{{- if .Output.List }}
71+
var reslist []json.RawMessage
72+
if err = json.Unmarshal([]byte(res.Res), &reslist); err != nil {
73+
return
74+
}
75+
for _, r := range reslist {
76+
v, err := decode{{ .Output.Type.Go }}(r)
77+
if err != nil {
78+
return nil, err
79+
}
80+
ret = append(ret, v)
81+
}
82+
{{- else }}
83+
return decode{{ .Output.Type.Go }}(res.Res)
84+
{{- end }}
85+
{{- else }}
86+
if err = json.Unmarshal([]byte(res.Res), &ret); err != nil {
87+
return
88+
}
89+
{{- end }}
90+
{{- end }}
91+
return
92+
}

0 commit comments

Comments
 (0)