Eric Blake <ebl...@redhat.com> writes: [...] > === Union types === > > -Union types are used to let the user choose between several different data > -types. A union type is defined using a dictionary as explained in the > -following paragraphs. > +Usage: { 'union': 'str', 'data': 'dict' } > +or: { 'union': 'str', 'data': 'dict', 'base': 'complex-type-name', > + 'discriminator': 'enum-member-of-base' } > +or: { 'union': 'str', 'data': 'dict', 'discriminator': {} } > > +Union types are used to let the user choose between several different > +data types. There are three flavors: simple (no discriminator), flat > +(a base type is mandatory, and discriminator is the name of an enum > +field within that base type), and anonymous (discriminator is an > +empty dictionary). A union type is defined using a data dictionary as > +explained in the following paragraphs. > > -A simple union type defines a mapping from discriminator values to data types > -like in this example: > +A simple union type defines a mapping from automatic discriminator > +values to data types like in this example: > > { 'type': 'FileOptions', 'data': { 'filename': 'str' } } > { 'type': 'Qcow2Options', > @@ -132,10 +273,17 @@ specified data type corresponding to the discriminator > value: > { "type": "qcow2", "data" : { "backing-file": "/some/place/my-image", > "lazy-refcounts": true } } > > +Additionally, an implicit C enum NameKind is created, corresponding to > +the union Name, for accessing the various branches of the union. No > +branch of the union can be named 'max', as this would collide with the > +implicit enum. > > -A union definition can specify a complex type as its base. In this case, the > -fields of the complex type are included as top-level fields of the union > -dictionary in the QMP wire format. An example definition is: > + > +A flat union definition specifies a complex type as its base, and > +avoids nesting on the wire. In this case, the fields of the complex > +type are included as top-level fields of the union dictionary in the > +QMP wire format, and the 'discriminator' field must be the name of an > +enum-typed member of the base type. An example definition is: > > { 'type': 'BlockdevCommonOptions', 'data': { 'readonly': 'bool' } } > { 'union': 'BlockdevOptions', 'base': 'BlockdevCommonOptions', 'data': { 'raw': 'RawOptions', 'qcow2': 'Qcow2Options' } }
Where's 'discriminator'? And it looks like this on the wire: { "type": "qcow2", "readonly": false, > "data" : { "backing-file": "/some/place/my-image", > "lazy-refcounts": true } } Is the variant part really wrapped in "data"? Here's the real schema's flat union BlockdevOptions: { 'union': 'BlockdevOptions', 'base': 'BlockdevOptionsBase', 'discriminator': 'driver', 'data': { 'qcow2': 'BlockdevOptionsQcow2', 'raw': 'BlockdevOptionsGenericFormat', [many more omitted...] } } Same thing, just different names. One the wire, it looks like { "driver": "qcow2", "id": "disk1", "file": { "driver": "file", "filename": "tmp.qcow2" } } > > - > -Flat union types avoid the nesting on the wire. They are used whenever a > -specific field of the base type is declared as the discriminator ('type' is > -then no longer generated). The discriminator must be of enumeration type. > -The above example can then be modified as follows: > +Notice that in a flat union, a 'type' field is no longer generated, > +and the keys of the 'data' dictionary must match the valid values for > +the discriminator (although not necessarily in the same order). The > +above example for simple unions can be modified to a flat union as > +follows: > > { 'enum': 'BlockdevDriver', 'data': [ 'raw', 'qcow2' ] } > { 'type': 'BlockdevCommonOptions', 'data': { 'driver': 'BlockdevDriver', 'readonly': 'bool' } } { 'union': 'BlockdevOptions', 'base': 'BlockdevCommonOptions', 'discriminator': 'driver', 'data': { 'raw': 'RawOptions', 'qcow2': 'Qcow2Options' } } Resulting in this JSON object: { "driver": "qcow2", "readonly": false, "backing-file": "/some/place/my-image", "lazy-refcounts": true } This actually matches the above example with the "data" wrapper peeled off the variant part. [...]