Open myitcv opened 5 months ago
@rogpeppe also flags this canonical examples from JSON Schema: https://json-schema.org/understanding-json-schema/reference/combining#oneOf
{
"oneOf": [
{ "type": "number", "multipleOf": 5 },
{ "type": "number", "multipleOf": 3 }
]
}
Adding one more example
We are facing troubles with correct code generation because oneOf
has allOf + not anyOf
import "strings"
#SpecialText: {
type: "special",
text: string & =~"^.{1,}$"
}
#MyText: {
content: strings.MinRunes(1) | #SpecialText
}
"components": {
"schemas": {
"MyText": {
"type": "object",
"required": [
"content"
],
"properties": {
"content": {
"oneOf": [
{
"allOf": [
{
"type": "string",
"minLength": 1
},
{
"not": {
"anyOf": [
{
"$ref": "#/components/schemas/SpecialText"
}
]
}
}
]
},
{
"$ref": "#/components/schemas/SpecialText"
}
]
}
}
},
"SpecialText": {
"type": "object",
"required": [
"type",
"text"
],
"properties": {
"type": {
"type": "string",
"enum": [
"special"
]
},
"text": {
"type": "string",
"pattern": "^.{1,}$"
}
}
}
}
}
I've just raised https://github.com/cue-lang/cue/issues/3380 to track the implementation of oneof
and related constraints using the new matchN
builtin.
What version of CUE are you using (
cue version
)?Does this issue reproduce with the latest release?
Yes
What did you do?
Capturing an issue that deals with how to encode one-ofs from JSON Schema, protocol buffers (and potentially other languages). #943 suggests one approach for encoding oneofs; this issue is a more general exploration of the space.
The example in question is from JSON Schema:
As can be seen from https://jsonschema.dev/s/5KO7a, this validates successfully when one field is present, and raises an error when both are specified https://jsonschema.dev/s/209Bo.
Turning to how this can be represented in CUE we have, AFAICT, two ways of doing this today:
Looking at how each behaves with both the old and new evaluator we see the following:
What did you expect to see?
Unclear.
Export of approach 2 succeeds, but I don't think it is a scaleable approach to encoding oneofs. It is also not readily understandable by humans. It's not incorrect however that the
cue export
succeeds in this case.Export of approach 1 fails. Given my understanding of when the required field is "checked", I think this therefore qualifies as "behaving as expected". But I'm not clear that this is the behaviour we want. I think it's reasonable to make the argument that
cue export
explicitly/implicitly says "I am not going to provide you with anything more". Through that lens, one could argue that the{y!: int}
disjunct in approach 1 can be eliminated, because it fails with respect to{x: 5}
, which would then allow the export to succeed.Hence there's an argument that the test should fail, because (if you will excuse the double negative) approach 1 should succeed and give the same output as approach 2.
What did you see instead?
Passing test.
Related issues
In raising this issue I suggest we consolidate conversation from the following issues:
Update: those issues have now been closed to consolidate discussion here.