Skip to content

Commit 20836a5

Browse files
author
Antoine Pelisse
committed
Define new schema for Unions
1 parent 8b93a2f commit 20836a5

File tree

2 files changed

+55
-5
lines changed

2 files changed

+55
-5
lines changed

schema/elements.go

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,15 @@ const (
8383

8484
// Struct represents a type which is composed of a number of different fields.
8585
// Each field has a name and a type.
86-
//
87-
// TODO: in the future, we will add one-of groups (sometimes called unions).
8886
type Struct struct {
8987
// Each struct field appears exactly once in this list. The order in
9088
// this list defines the canonical field ordering.
9189
Fields []StructField `yaml:"fields,omitempty"`
9290

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
9592
// one or more fields in the above list. A given field from the above
9693
// 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"`
9895

9996
// ElementRelationship states the relationship between the struct's items.
10097
// * `separable` (or unset) implies that each element is 100% independent.
@@ -108,6 +105,45 @@ type Struct struct {
108105
ElementRelationship ElementRelationship `yaml:"elementRelationship,omitempty"`
109106
}
110107

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+
111147
// StructField pairs a field name with a field type.
112148
type StructField struct {
113149
// Name is the field name.

schema/schemaschema.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,23 @@ var SchemaSchemaYAML = `types:
8484
namedType: structField
8585
elementRelationship: associative
8686
keys: [ "name" ]
87+
- name: union
88+
type:
89+
namedType: union
8790
- name: elementRelationship
8891
type:
8992
scalar: string
93+
- name: union
94+
struct:
95+
fields:
96+
- name: discriminator
97+
type:
98+
scalar: string
99+
- name: fields
100+
type:
101+
map:
102+
elementType:
103+
scalar: string
90104
- name: structField
91105
struct:
92106
fields:

0 commit comments

Comments
 (0)