On Fri, Sep 29, 2023 at 03:29:34PM +0200, Victor Toso wrote: > Hi, > > On Thu, Sep 28, 2023 at 03:06:23PM +0100, Daniel P. Berrangé wrote: > > On Wed, Sep 27, 2023 at 01:25:38PM +0200, Victor Toso wrote: > > > This patch handles QAPI struct types and generates the equivalent > > > types in Go. The following patch adds extra logic when a member of the > > > struct has a Type that can take JSON Null value (e.g: StrOrNull in > > > QEMU) > > > > > > The highlights of this implementation are: > > > > > > 1. Generating an Go struct that requires a @base type, the @base type > > > fields are copied over to the Go struct. The advantage of this > > > approach is to not have embed structs in any of the QAPI types. > > > Note that embedding a @base type is recursive, that is, if the > > > @base type has a @base, all of those fields will be copied over. > > > > > > 2. About the Go struct's fields: > > > > > > i) They can be either by Value or Reference. > > > > > > ii) Every field that is marked as optional in the QAPI specification > > > are translated to Reference fields in its Go structure. This > > > design decision is the most straightforward way to check if a > > > given field was set or not. Exception only for types that can > > > take JSON Null value. > > > > > > iii) Mandatory fields are always by Value with the exception of QAPI > > > arrays, which are handled by Reference (to a block of memory) by > > > Go. > > > > > > iv) All the fields are named with Uppercase due Golang's export > > > convention. > > > > > > v) In order to avoid any kind of issues when encoding or decoding, > > > to or from JSON, we mark all fields with its @name and, when it is > > > optional, member, with @omitempty > > > > > > Example: > > > > > > qapi: > > > | { 'struct': 'BlockdevCreateOptionsFile', > > > | 'data': { 'filename': 'str', > > > | 'size': 'size', > > > | '*preallocation': 'PreallocMode', > > > | '*nocow': 'bool', > > > | '*extent-size-hint': 'size'} } > > > > > > go: > > > | type BlockdevCreateOptionsFile struct { > > > | Filename string `json:"filename"` > > > | Size uint64 `json:"size"` > > > | Preallocation *PreallocMode `json:"preallocation,omitempty"` > > > | Nocow *bool `json:"nocow,omitempty"` > > > | ExtentSizeHint *uint64 `json:"extent-size-hint,omitempty"` > > > | } > > > > Note, 'omitempty' shouldn't be used on pointer fields, only > > scalar fields. The pointer fields are always omitted when nil. > > 'omitempty' should be used with pointer fields unless you want to > Marshal JSON Null, which is not the expected output.
Oh doh, did't notice that. With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|