@@ -83,18 +83,15 @@ const (
83
83
84
84
// Struct represents a type which is composed of a number of different fields.
85
85
// Each field has a name and a type.
86
- //
87
- // TODO: in the future, we will add one-of groups (sometimes called unions).
88
86
type Struct struct {
89
87
// Each struct field appears exactly once in this list. The order in
90
88
// this list defines the canonical field ordering.
91
89
Fields []StructField `yaml:"fields,omitempty"`
92
90
93
- // TODO: Implement unions, either this way or by inlining.
94
- // Unions are groupings of fields with special rules. They may refer to
91
+ // Union is a grouping of fields with special rules. It may refer to
95
92
// one or more fields in the above list. A given field from the above
96
93
// list may be referenced in exactly 0 or 1 places in the below list.
97
- // Unions [] Union `yaml:"unions ,omitempty"`
94
+ Union * Union `yaml:"union ,omitempty"`
98
95
99
96
// ElementRelationship states the relationship between the struct's items.
100
97
// * `separable` (or unset) implies that each element is 100% independent.
@@ -108,6 +105,45 @@ type Struct struct {
108
105
ElementRelationship ElementRelationship `yaml:"elementRelationship,omitempty"`
109
106
}
110
107
108
+ // UnionFields are mapping between the fields that are part of the union and
109
+ // their discriminated value. The discriminated value has to be set, and
110
+ // should not conflict with other discriminated value in the list.
111
+ type UnionField struct {
112
+ // FieldName is the name of the field that is part of the union. This
113
+ // is the serialized form of the field.
114
+ FieldName string `yaml:"fieldName"`
115
+ // DiscriminatedBy is the value of the discriminator to select that
116
+ // field.
117
+ DiscriminatedBy string `yaml:"DiscriminatedBy"`
118
+ }
119
+
120
+ // Union, or oneof, means that only one of multiple fields of a structure can be
121
+ // set at a time. For backward compatibility reasons, and to help "dumb clients"
122
+ // which are not aware of the union (or can't be aware of it because they
123
+ // don't know what fields are part of the union), the code tolerates multiple
124
+ // fields to be set but will try to detect which fields must be cleared (there
125
+ // should never be more than two though):
126
+ // - If there is a discriminator and its value has changed, clear all fields
127
+ // but the one specified by the discriminator
128
+ // - If there is no discriminator, or it hasn't changed, if new has two of the
129
+ // fields set, remove the one that was set in old.
130
+ // - If there is a discriminator, set it to the value we've kept (if it changed)
131
+ type Union struct {
132
+ // Discriminator, if present, is the name of the field that
133
+ // discriminates fields in the union. The mapping between the value of
134
+ // the discriminator and the field is done by using the Fields list
135
+ // below.
136
+ Discriminator * string `yaml:"discriminator,omitempty"`
137
+
138
+ // This is the list of fields that belong to this union. This fields are
139
+ // required to not be part of another union, or be the discriminator for
140
+ // another union. All the fields present in here have to be part of the
141
+ // parent structure. Discriminator (if oneOf has one), is NOT included
142
+ // in this list. The value for field is how we map the name of the field
143
+ // to actual value for discriminator.
144
+ Fields []UnionField `yaml:"fields,omitempty"`
145
+ }
146
+
111
147
// StructField pairs a field name with a field type.
112
148
type StructField struct {
113
149
// Name is the field name.
0 commit comments