This repository has been archived by the owner on Nov 18, 2021. It is now read-only.
Replies: 2 comments 1 reply
-
Maybe one of these tricks helps:
|
Beta Was this translation helpful? Give feedback.
1 reply
-
This discussion has been migrated to cue-lang/cue#889. For more details about CUE's migration to a new home, please see cue-lang/cue#1078. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I am attempting to use CUE to specify a schema for a fairly permissive data structure. I have defined much of this permissiveness through the use of disjunctions, and I am running into trouble, it seems, because I have assumed that disjunctions will resolve based on completeness, which is not the case.
For a simplified example, I have a top-level field which is can be a single type or a list of one or more of this type. The type is then defined as a disjunction of two different struct types which have overlapping but not identical fields:
At this point,
topField
is considered incomplete, because it resolves to{commonField:"foo",uniqueField:string,type:"A"} | {commonField:"foo",type:"B"}
The
#TypeA
side of the disjunction is not eliminated because it is still a valid cue value. In order for it to be eliminated, it would have to resolve to_|_
.I can work around this somewhat by preferencing
#TypeB
in the disjunction:This will work so long as I only have two options in the disjunction, but it doesn't help if I want the types to be open -- then
#TypeB
will always be selected, as it is above.I have made a semi-successful attempt at solving this by explicitly defining some logic based on the existence of
uniqueField
, as follows:What this tries to do is force a
type: "A" & type: "B"
conflict that eliminates#TypeB
from the disjunction when theuniqueField
exists ontopField
. I could make this invisible on export by using the_type
underscore convention.However, this is very inflexible, as it relies on a direct reference to
topField
and I want this logic to be "built in" to#FieldType
, so I can use the[#FieldType, ...#FieldType] | #FieldType
form in my first example. It is also still awkward to use the preference mark*
, but there doesn't seem to be a different way to eliminate the#TypeA
side of the disjunction, astopField.uniqueField == _|_
does not appear to ever return true.I think ideally what I would be looking for is something that could be applied directly to the
#FieldType
definition, like#FieldType: concreteof(#TypeA | #TypeB)
, or-- but I don't think this is supported by the language at this time.
My fallback option is to forego this level of specificity in the schema and just use a single type with an optional
uniqueField
, instead of having#TypeA
,#TypeB
, and the disjunction at all. My sense is that disjunctions are better used when they can be considered "normalized", which seems in practice to mean that all of the options are of different non-struct types, or of structs with no possibility of "overlap" either by virtue of being open or by containing the same fields.Beta Was this translation helpful? Give feedback.
All reactions