[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH v1 7/8] qapi: golang: Add CommandResult type to Go
From: |
Victor Toso |
Subject: |
[RFC PATCH v1 7/8] qapi: golang: Add CommandResult type to Go |
Date: |
Sat, 2 Apr 2022 00:41:03 +0200 |
This patch adds a struct type in Go that will handle return values for
QAPI's command types.
The return value of a Command is, encouraged to be, QAPI's complext
types or an Array of those.
The 'CommandResult' type acts in similar fashion to 'Event' and
'Command', in order to map the right return data structure based on
the issued 'Command'.
This patch also adds a syntax sugar method to 'Command' to return the
'CommandResult' struct to use when receiving the return data.
Example:
```go
cmd := Command{}
cmd.Name = `query-tpm-models`
// bytes, _ := json.Marshal(&cmd)
// send bytes ...
received := `{"return":["tpm-tis","tpm-crb","tpm-spapr"]}`
cmdRet := cmd.GetReturnType()
_ = json.Unmarshal([]byte(received), &cmdRet)
// cmdRet.Value.([]TpmModel)[2] == TpmModelTpmSpapr
```
Signed-off-by: Victor Toso <victortoso@redhat.com>
---
scripts/qapi/golang.py | 42 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 40 insertions(+), 2 deletions(-)
diff --git a/scripts/qapi/golang.py b/scripts/qapi/golang.py
index 0b9c19babb..5d3395514d 100644
--- a/scripts/qapi/golang.py
+++ b/scripts/qapi/golang.py
@@ -36,6 +36,7 @@ def __init__(self, prefix: str):
self.schema = None
self.events = {}
self.commands = {}
+ self.command_results = {}
self._docmap = {}
self.golang_package_name = "qapi"
@@ -90,6 +91,32 @@ def visit_end(self):
'''
self.target["command"] += generate_marshal_methods('Command',
self.commands)
+ self.target["command"] += '''
+type CommandResult struct {
+ CommandBase
+ Value Any `json:"return,omitempty"`
+}
+
+func (s Command) GetReturnType() CommandResult {
+ return CommandResult{
+ CommandBase: s.CommandBase,
+ }
+}
+
+// In order to evaluate nil value to empty JSON object
+func (s *CommandResult) MarshalJSON() ([]byte, error) {
+ if s.Value == nil {
+ return []byte(`{"return":{}}`), nil
+ }
+ tmp := struct {
+ Value Any `json:"return"`
+ }{Value: s.Value}
+
+ return json.Marshal(&tmp)
+}
+'''
+ self.target["command"] += generate_marshal_methods('CommandResult',
self.command_results)
+
self.target["helper"] += '''
// Creates a decoder that errors on unknown Fields
// Returns true if successfully decoded @from string @into type
@@ -312,6 +339,9 @@ def visit_command(self,
assert name == info.defn_name
type_name = qapi_to_go_type_name(name, info.defn_meta)
self.commands[name] = type_name
+ if ret_type:
+ ret_type_name = qapi_schema_type_to_go_type(ret_type.name)
+ self.command_results[name] = ret_type_name
doc = self._docmap.get(name, None)
self_contained = True if not arg_type or not
arg_type.name.startswith("q_obj") else False
@@ -445,6 +475,11 @@ def generate_marshal_methods(type: str,
discriminator = "base.Name"
struct_field = "Arg"
json_field = "arguments"
+ elif type == "CommandResult":
+ base = "CommandBase"
+ discriminator = "s.Name"
+ struct_field = "Value"
+ json_field = "return"
else:
assert base != ""
discriminator = "base." + discriminator
@@ -527,14 +562,17 @@ def generate_marshal_methods(type: str,
return []byte(result), nil
}}
'''
- unmarshal_base = f'''
+ unmarshal_base = ""
+ unmarshal_default_warn = ""
+ if type != "CommandResult":
+ unmarshal_base = f'''
var base {base}
if err := json.Unmarshal(data, &base); err != nil {{
return err
}}
s.{base} = base
'''
- unmarshal_default_warn = f'''
+ unmarshal_default_warn = f'''
default:
fmt.Println("Failed to decode {type}", {discriminator})'''
--
2.35.1
- [RFC PATCH v1 0/8] qapi: add generator for Golang interface, Victor Toso, 2022/04/01
- [RFC PATCH v1 1/8] qapi: golang: Generate qapi's enum types in Go, Victor Toso, 2022/04/01
- [RFC PATCH v1 2/8] qapi: golang: Generate qapi's alternate types in Go, Victor Toso, 2022/04/01
- [RFC PATCH v1 3/8] qapi: golang: Generate qapi's struct types in Go, Victor Toso, 2022/04/01
- [RFC PATCH v1 4/8] qapi: golang: Generate qapi's union types in Go, Victor Toso, 2022/04/01
- [RFC PATCH v1 5/8] qapi: golang: Generate qapi's event types in Go, Victor Toso, 2022/04/01
- [RFC PATCH v1 7/8] qapi: golang: Add CommandResult type to Go,
Victor Toso <=
- [RFC PATCH v1 8/8] qapi: golang: document skip function visit_array_types, Victor Toso, 2022/04/01
- [RFC PATCH v1 6/8] qapi: golang: Generate qapi's command types in Go, Victor Toso, 2022/04/01
- Re: [RFC PATCH v1 0/8] qapi: add generator for Golang interface, Andrea Bolognani, 2022/04/19
- Re: [RFC PATCH v1 0/8] qapi: add generator for Golang interface, Markus Armbruster, 2022/04/26