this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

encoding/jsonschema: support boolean-valued schemas

From draft-06 onwards, any schema can be a boolean,
with true signifying "always validates" and false signifying
"never validates".

In passing, make the various places that create a "top"
value use a common implementation.

Fixes #1168.

Signed-off-by: Roger Peppe <rogpeppe@gmail.com>
Change-Id: I9e29c17f911ea7bdf37bd4764b904eb4991fe915
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1199563
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>

+62 -12
+1 -1
encoding/jsonschema/constraints_array.go
··· 82 82 s.errf(n, "invalid uint") 83 83 } 84 84 for ; p > 0; p-- { 85 - a = append(a, ast.NewIdent("_")) 85 + a = append(a, top()) 86 86 } 87 87 s.add(n, arrayType, ast.NewList(append(a, &ast.Ellipsis{})...)) 88 88
+3 -2
encoding/jsonschema/constraints_object.go
··· 69 69 x := ast.NewCall(ast.NewSel(pkg, "MaxFields"), s.uint(n)) 70 70 s.add(n, objectType, x) 71 71 } 72 + 72 73 func constraintPatternProperties(key string, n cue.Value, s *state) { 73 74 if n.Kind() != cue.StructKind { 74 75 s.errf(n, `value of "patternProperties" must be an object, found %v`, n.Kind()) ··· 125 126 func constraintPropertyNames(key string, n cue.Value, s *state) { 126 127 // [=~pattern]: _ 127 128 if names, _ := s.schemaState(n, cue.StringKind, nil, false); !isAny(names) { 128 - x := ast.NewStruct(ast.NewList(names), ast.NewIdent("_")) 129 + x := ast.NewStruct(ast.NewList(names), top()) 129 130 s.add(n, objectType, x) 130 131 } 131 132 } ··· 159 160 if f == nil && ok { 160 161 f := &ast.Field{ 161 162 Label: ast.NewString(str), 162 - Value: ast.NewIdent("_"), 163 + Value: top(), 163 164 Constraint: token.NOT, 164 165 } 165 166 fields[str] = f
+27 -9
encoding/jsonschema/decode.go
··· 427 427 if s.allowedTypes == 0 { 428 428 // Nothing is possible. 429 429 s.addErr(errors.Newf(s.pos.Pos(), "constraints are not possible to satisfy")) 430 - return &ast.BottomLit{} 430 + return bottom() 431 431 } 432 432 433 433 conjuncts := []ast.Expr{} ··· 522 522 // s.allowedTypes is non-zero (so we know that 523 523 // it's not bottom) and we need _some_ expression 524 524 // to be part of the subequent syntax, we use top. 525 - e = ast.NewIdent("_") 525 + e = top() 526 526 } else { 527 527 e = ast.NewBinExpr(token.AND, conjuncts...) 528 528 } ··· 576 576 // need to be mentioned again. 577 577 s.knownTypes = s.allowedTypes 578 578 return e 579 - } 580 - 581 - func isAny(s ast.Expr) bool { 582 - i, ok := s.(*ast.Ident) 583 - return ok && i.Name == "_" 584 579 } 585 580 586 581 func (s *state) comment() *ast.CommentGroup { ··· 618 613 // types holds the set of possible types that the value can hold. 619 614 // idRef holds the path to the value. 620 615 // isLogical specifies whether the caller is a logical operator like anyOf, allOf, oneOf, or not. 621 - func (s *state) schemaState(n cue.Value, types cue.Kind, idRef []label, isLogical bool) (_e ast.Expr, _ *state) { 616 + func (s *state) schemaState(n cue.Value, types cue.Kind, idRef []label, isLogical bool) (ast.Expr, *state) { 622 617 state := &state{ 623 618 up: s, 624 619 schemaVersion: s.schemaVersion, ··· 633 628 if isLogical { 634 629 state.parent = s 635 630 } 631 + if n.Kind() == cue.BoolKind { 632 + if vfrom(versionDraft06).contains(state.schemaVersion) { 633 + // From draft-06 onwards, boolean values signify a schema that always passes or fails. 634 + if state.boolValue(n) { 635 + return top(), state 636 + } 637 + return bottom(), state 638 + } 639 + return s.errf(n, "boolean schemas not supported in %v", state.schemaVersion), state 640 + } 636 641 637 642 if n.Kind() != cue.StructKind { 638 643 return s.errf(n, "schema expects mapping node, found %s", n.Kind()), state ··· 755 760 return &ast.UnaryExpr{Op: token.NMAT, X: ast.NewString(re)} 756 761 } 757 762 763 + func bottom() ast.Expr { 764 + return &ast.BottomLit{} 765 + } 766 + 767 + func top() ast.Expr { 768 + return ast.NewIdent("_") 769 + } 770 + 771 + func isAny(s ast.Expr) bool { 772 + i, ok := s.(*ast.Ident) 773 + return ok && i.Name == "_" 774 + } 775 + 758 776 func addTag(field ast.Label, tag, value string) *ast.Field { 759 777 return &ast.Field{ 760 778 Label: field, 761 - Value: ast.NewIdent("_"), 779 + Value: top(), 762 780 Attrs: []*ast.Attribute{ 763 781 {Text: fmt.Sprintf("@%s(%s)", tag, value)}, 764 782 },
+10
encoding/jsonschema/testdata/boolschema.txtar
··· 1 + -- type.json -- 2 + { 3 + "anyOf": [ 4 + true, 5 + false 6 + ] 7 + } 8 + 9 + -- out/decode/cue -- 10 + _ | _|_
+9
encoding/jsonschema/testdata/boolschema_oldversion.txtar
··· 1 + -- type.json -- 2 + { 3 + "$schema": "http://json-schema.org/draft-04/schema#", 4 + "anyOf": [true] 5 + } 6 + 7 + -- out/decode/err -- 8 + boolean schemas not supported in http://json-schema.org/draft-04/schema#: 9 + type.json:3:12
+12
encoding/jsonschema/testdata/boolschemaembed.txtar
··· 1 + -- type.json -- 2 + { 3 + "$defs": { 4 + "foo": true 5 + }, 6 + "$ref": "#/$defs/foo", 7 + "type": "string" 8 + } 9 + -- out/decode/cue -- 10 + #foo & string 11 + 12 + #foo: _