Data sometimes needs to include values for one of several mutually exclusive
fields, or combinations of those fields.
The built-in function matchN
can be used to describe constraints such as
“require exactly one of these fields”, or “permit up to two of these fields”.
This guide demonstrates how to use matchN
as a field validator to enforce
different scenarios where you need to limit the combinations of which fields
are allowed.
package matchn
// A and B have identical matchN constraints of
// "allow at most two of these named fields".
A: {
matchN(<=2, [{alpha!: _}, {beta!: _}, {gamma!: _}])
alpha: "foo"
beta: "bar"
}
B: matchN(<=2, [{alpha!: _}, {beta!: _}, {gamma!: _}])
B: {
alpha: "foo"
beta: "bar"
gamma: "baz"
}
$ cue vet -c
B: invalid value {alpha:"foo",beta:"bar",gamma:"baz"} (does not satisfy matchN): 3 matched, expected <=2:
./example.cue:12:4
./example.cue:12:11
./example.cue:13:4
All matchN
constraints require two parameters:
- The second parameter is a list of constraints. CUE counts how many of
these constraints are able to unify successfully with the field that’s being
validated (
A
andB
, in our example). - The first parameter is a number constraint. For a field to be valid, this constraint must be able to unify successfully with the count produced when CUE tested the list of constraints.
This flexible logic allows for a wide variety of requirements to be expressed
using similar matchN
validators. With the list of constraints shown in the
examples above, a different number constraint would enforce requirements such
as:
- Require exactly one of these fields:
1
- Allow up to two of these fields:
<=2
(also<3
) - Require at least one of these fields:
>=1
(also>0
) - Require between two and four of these fields:
>=2 & <=4
(also2 | 3 | 4
) - Require either one,
or three of these fields:
1 | 3
- Require either less than three,
or exactly four,
or more than five of these fields:
<3 | 4 | >5
(also!=3 & !=5
) - Disallow exactly two of these fields:
!=2
(also<2 | >2
)
The different encodings that CUE allows for individual number constraints gives
you flexibility – you can choose the form that communicates your intent most
clearly, given your specific situation. For example, >=2 & <=4
and 2 | 3 | 4
are equivalent in a matchN
number constraint, but you might find one
more appropriate than the other.
The function’s parameters can also be resolved via references, which helps
avoid the matchN
duplication shown in the example CUE above. Learn more in
Using the built-in function "matchN" as a field validator
Related content
- How-to Guide: Using the built-in function "matchN" as a field validator
- Standard library:
struct.MinFields
&struct.MaxFields
– limit the total number of fields present in a struct