From 313830165aad2e1659c27a46527a2f006e2c5605 Mon Sep 17 00:00:00 2001 From: haoqixu Date: Fri, 16 Aug 2024 17:55:10 +0800 Subject: [PATCH] encoding/jsonschema: decode `contains` as `list.MatchN` The `contains` keyword accepts any valid JSON Schema which is decoded as a non-concrete constraint. However the `list.Contains` validator checks for equality and expects its second argument to be concrete. This change uses `list.MatchN` to support the `contains` keyword. Fixes #3367 Change-Id: I454a1f6166db3195e4003eb2512e6d550e041cdf Signed-off-by: haoqixu Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1199603 Reviewed-by: Roger Peppe Unity-Result: CUE porcuepine TryBot-Result: CUEcueckoo --- encoding/jsonschema/constraints_array.go | 11 ++++++----- encoding/jsonschema/testdata/contains.txtar | 13 +++++++++++++ encoding/jsonschema/testdata/list.txtar | 8 +++++++- 3 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 encoding/jsonschema/testdata/contains.txtar diff --git a/encoding/jsonschema/constraints_array.go b/encoding/jsonschema/constraints_array.go index e72082b076e..daddb0118fe 100644 --- a/encoding/jsonschema/constraints_array.go +++ b/encoding/jsonschema/constraints_array.go @@ -40,11 +40,12 @@ func constraintAdditionalItems(key string, n cue.Value, s *state) { func constraintContains(key string, n cue.Value, s *state) { list := s.addImport(n, "list") - // TODO: Passing non-concrete values is not yet supported in CUE. - if x := s.schema(n); !isAny(x) { - x := ast.NewCall(ast.NewSel(list, "Contains"), clearPos(x)) - s.add(n, arrayType, x) - } + x := s.schema(n) + x = ast.NewCall(ast.NewSel(list, "MatchN"), &ast.UnaryExpr{ + Op: token.GEQ, + X: ast.NewLit(token.INT, "1"), + }, clearPos(x)) + s.add(n, arrayType, x) } func constraintItems(key string, n cue.Value, s *state) { diff --git a/encoding/jsonschema/testdata/contains.txtar b/encoding/jsonschema/testdata/contains.txtar new file mode 100644 index 00000000000..de637991052 --- /dev/null +++ b/encoding/jsonschema/testdata/contains.txtar @@ -0,0 +1,13 @@ +-- schema.yaml -- +type: object +properties: + p1: + type: array + contains: {} + +additionalProperties: false + +-- out/decode/extract -- +import "list" + +p1?: list.MatchN(>=1, _) diff --git a/encoding/jsonschema/testdata/list.txtar b/encoding/jsonschema/testdata/list.txtar index e8e79ae805d..07e7947851a 100644 --- a/encoding/jsonschema/testdata/list.txtar +++ b/encoding/jsonschema/testdata/list.txtar @@ -19,6 +19,11 @@ properties: contains: const: 3 + too: + type: array + contains: + type: string + size: type: array minItems: 3 @@ -40,7 +45,8 @@ import "list" foo?: [...string] tuple?: [string, int, 2] -has?: list.Contains(3) +has?: list.MatchN(>=1, 3) +too?: list.MatchN(>=1, string) size?: list.UniqueItems() & list.MaxItems(9) & [_, _, _, ...] additional?: [int, int, ...string] -- out/decode/testerr/err-foo-not-string --